MVVM风格的TreeView元素上的ContextMenu [英] ContextMenu on TreeView-Element in MVVM-style
问题描述
我有一个简单任务,可以在以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
推荐答案
您很亲密。
您在做什么:
- 您设置
TreeView
的标签标记为其自己的DataContext
。这是不必要的
。 - 您尝试从
ContextMenu.PlacementTarget获得
-Tag.MyText
TextBlock
。TextBlock
没有设置Tag
。
- you set the
Tag
ofTreeView
to its ownDataContext
. This is unnecessary. - you try to get
Tag.MyText
from yourContextMenu.PlacementTarget
- which isTextBlock
. TheTextBlock
has noTag
set.
您应该做什么:
- 设置
标记
TextBlock 到窗口
的DataContext
(窗口是TextBlock
祖先,您应该通过
RelativeSource Mode = FindAncestor
)查找它。 - 第二部分没问题-您有
TextBlock.Tag
设置为第一步。
- set the
Tag
of the TextBlock toDataContext
of the Window (Window isTextBlock
ancestor and you should look it up viaRelativeSource Mode=FindAncestor
). - the second part is OK - you have
TextBlock.Tag
set in the first step.
这篇关于MVVM风格的TreeView元素上的ContextMenu的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!