MVVM风格的TreeView元素上的ContextMenu [英] ContextMenu on TreeView-Element in MVVM-style

查看:81
本文介绍了MVVM风格的TreeView元素上的ContextMenu的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单任务,可以在以MVVM方式完成的TreeView(Element)上具有ContextMenu。
在网上搜索时,我发现可以使用按钮等解决方案,但不能使用TreeView。我认为问题出在设置TreeView的ItemsSource-Property上,从而为每个项目提供自己的DataContext。

I have the "simple" task to have a ContextMenu on a TreeView(Element) that is done in MVVM-way. When searching the web I found some solutions that I could bring to work with buttons etc. but not with the TreeView. I think the problem is with setting the ItemsSource-Property of TreeView that gives every single item an own DataContext.

这是我的小Test-App,您可以在其中看到原理按钮而不是TreeView元素:

Here's my little Test-App where you can see the principle working for button but not for the TreeView-Elements:

MainWindow.xaml:

<Window x:Class="ContextMenu.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <Grid >
        <StackPanel>
            <TextBlock Text="{Binding MyText}" />

            <Button Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=Self}}" Content="Click me">
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="{Binding PlacementTarget.Tag.MyText,
                            RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" />
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>

            <TreeView ItemsSource="{Binding MyList}" Tag="{Binding DataContext, RelativeSource={RelativeSource Mode=Self}}">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate>
                        <TextBlock Text="{Binding Name}">
                            <TextBlock.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="{Binding Path=PlacementTarget.Tag.MyText, 
                                        RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" />
                                </ContextMenu>
                            </TextBlock.ContextMenu>
                        </TextBlock>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>         
            </TreeView>

        </StackPanel>        
    </Grid>
</Window>

代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowVM();
    }
}

MainWindowVM.cs:

public class MainWindowVM
{
    public string MyText { get; set; }
    public ObservableCollection<TreeElement> MyList { get; set; }

    public MainWindowVM()
    {
        MyText = "This is my Text!";
        MyList = new ObservableCollection<TreeElement>();
        MyList.Add(new TreeElement("String 1"));
        MyList.Add(new TreeElement("String 2"));
    }
}

public class TreeElement
{
    public string Name { get; set; }
    public TreeElement(string Name)
    {
        this.Name = Name;
    }
}

感谢您的帮助!
Joerg

Thanks for your help!! Joerg

推荐答案

您很亲密。

您在做什么:


  1. 您设置 TreeView 的标签标记为其自己的 DataContext 。这是不必要的

  2. 您尝试从 ContextMenu.PlacementTarget获得 Tag.MyText - TextBlock TextBlock 没有设置 Tag

  1. you set the Tag of TreeView to its own DataContext. This is unnecessary.
  2. you try to get Tag.MyText from your ContextMenu.PlacementTarget - which is TextBlock. The TextBlock has no Tag set.

您应该做什么:


  1. 设置标记 TextBlock 到窗口
    DataContext (窗口是 TextBlock 祖先,您应该通过
    RelativeSource Mode = FindAncestor )查找它。

  2. 第二部分没问题-您有 TextBlock.Tag 设置为第一步。

  1. set the Tag of the TextBlock to DataContext of the Window (Window is TextBlock ancestor and you should look it up via RelativeSource Mode=FindAncestor).
  2. the second part is OK - you have TextBlock.Tag set in the first step.

这篇关于MVVM风格的TreeView元素上的ContextMenu的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆