TreeView的上下文菜单绑定

3

我有一个简单的任务,需要将上下文菜单绑定到TreeView中的项目。如果我静态定义上下文菜单没有问题。但是如果我想将上下文菜单绑定到我的“根”数据上下文时,事情开始变得复杂。到目前为止,我还没有找到正确的方法将我的上下文菜单绑定到TreeView使用的原始DataContext。需要什么样的绑定魔法才能使其正常工作?这个绑定不起作用:

  <MenuItem Name="Name" Header="{Binding Path=DataContext.ContextMenuName, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeView}}}" />

以下是完整的示例:
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:ui="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TreeView ItemsSource="{Binding Path=Persons, Mode=OneTime}" Name="cTree">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate>
                    <TextBox Text="{Binding Mode=OneWay}">
                        <TextBox.ContextMenu>
                            <ContextMenu>
                                <MenuItem Name="Name" Header="{Binding Path=DataContext.ContextMenuName, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeView}}}" />
                            </ContextMenu>
                        </TextBox.ContextMenu>
                    </TextBox>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>



public partial class MainWindow : Window
{
    public string[] Persons
    {
        get { return new string[] { "Alois", "Kraus", "Joe", "xxxx" }; }
    }

    public string ContextMenuName
    {
        get;
        set;
    }

    public MainWindow()
    {
        ContextMenuName = "This is the data bound menu name";
        InitializeComponent();
        this.DataContext = this;
    }
}

基本上,我想绑定主窗体的属性ContextMenuName(实际上是我的ViewModel中的一个命令)。由于TreeView正在将其子项重新绑定到Persons(为简单起见,使用字符串),我无法从中获取根DataContext。到目前为止,我从未能找到任何祖先(TreeView或MainWindow),这应该解决问题,我在这里做错了什么?

2个回答

6
ContextMenu在应用于的控件上并不在同一可视树中,因此FindAncestor无法获取到树形视图(TreeView),因为它不是上下文菜单(ContextMenu)的祖先。
此外,ElementName也不起作用,因为它还需要两个控件在同一可视树中。
您可以使用x:Reference,即使它们不在同一可视树中也可以绑定。
<MenuItem Name="Name" 
          Header="{Binding Path=DataContext.ContextMenuName,
                           Source={x:Reference cTree}}" />

2
成功了!我读了很多关于数据绑定的SO问题,但在我的搜索中从未出现过Source和Reference。非常感谢,这个问题让我浪费了很多时间。 - Alois Kraus
1
在你解决我的问题之前,可能要搜索4-6个小时。+1。 - user2509848

0
你尝试过使用ElementName=cTree进行绑定,而不是RelativeSource={...}吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接