[英]Binding property in ContextMenu from Parent's Parent's DataContext
I wanted to bind a property in a MenuItem
within an ItemsControl
container. 我想在
ItemsControl
容器内的MenuItem
绑定一个属性。 I have a hierarchical model ; 我有一个层次模型;
Item
class has a list of SubItem
. Item
类具有SubItem
列表。 The ViewModel
itself has a list of Item
(so there's two ItemsControl
, one being in the ItemTemplate
of the other). ViewModel
本身有一个Item
列表(所以有两个ItemsControl
,一个在另一个的ItemTemplate
中)。
I found several other questions on SO asking about that ( this one for instance ) and I learned that the Visual Tree of a ContextMenu
is separated from the rest. 我在SO上发现了其他几个问题( 例如 , 这个问题),并且我了解到
ContextMenu
的可视树与其余ContextMenu
分开了。
I managed to do it and it works (but it feels kind of hacky) by "transferring" the model's data via the Tag
property. 我设法做到了,并且通过
Tag
属性“传输”了模型的数据,它可以工作(但感觉有点怪异)。
Here's the two model classes: 这是两个模型类:
public class SubItem
{
public int Current { get; set; }
public Subitem(int current)
{
Current = current;
}
}
public class Item
{
public ObservableCollection<SubItem> SubItems { get; set; }
public string Parent { get; set; }
public Item(string Parent)
{
Parent = Parent;
SubItems = new ObservableCollection<SubItem>();
}
}
Here's the view model: 这是视图模型:
public class ViewModel
{
public ObservableCollection<Item> Items { get; set; }
public ViewModel()
{
Items = new ObservableCollection<Item>();
FillData();
}
private void FillData()
{
//...
}
}
And here's the ItemsControl
at the root of the page (the page's DataContext
is an instance of the ViewModel
class): 这是页面根目录中的
ItemsControl
(页面的DataContext
是ViewModel
类的实例):
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding SubItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Current}"
Tag="{Binding DataContext.Parent, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}, Mode=FindAncestor}}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}, Mode=FindAncestor}}"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
My question is: is this the right way to do it? 我的问题是:这是正确的方法吗? I tried many other ways to avoid binding the property to the
Tag
but couldn't make it work. 我尝试了许多其他方法来避免将属性绑定到
Tag
但是无法使其正常工作。
The ugly part is specifically: 丑陋的部分是:
Tag="{Binding DataContext.Parent, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}, Mode=FindAncestor}}"
Followed by: 其次是:
Header="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}, Mode=FindAncestor}}"
I think it's kind of ugly and I'm sure there's a better way to do that. 我认为这很丑陋,而且我敢肯定有更好的方法可以做到这一点。 The solution must work with
.NET 4.0
. 该解决方案必须与
.NET 4.0
。
You need to add a tag to the menu's container and bind to it using placement target. 您需要在菜单的容器中添加标签,然后使用放置目标将其绑定。
View this example: 查看此示例:
<StackPanel x:Key="ConfigurationListItem" x:Shared="False" Tag="{Binding ElementName=UserControl}">
<StackPanel Orientation="Horizontal">
<Button>
<Button.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding ElementName=UserControl, Path=LaunchCommand}" CommandParameter="{Binding}" />
<MouseBinding Gesture="LeftClick" Command="{Binding ElementName=UserControl, Path=SelectCommand}" CommandParameter="{Binding}" />
</Button.InputBindings>
</StackPanel>
<StackPanel.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" Tag="{Binding}">
<MenuItem Header="Sync Environment Dependencies"
Command="{Binding Parent.PlacementTarget.Tag.SyncEnvironmentCommand, RelativeSource={RelativeSource Self}}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext}" />
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.