我的任务是在treeview中使用contextmenu,然后通过单击contextmenu元素将选定的treeview的项目传递给ViewModel。
这是我的xaml:
<Window.Resources>
<HierarchicalDataTemplate x:Key="Ufps"
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" />
<TextBlock Margin="5 0 0 0" Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
........
........
<TreeView x:Name="TrvUfpsDictionary" Height="222" Canvas.Left="25"
Canvas.Top="280" Width="545"
Background="AliceBlue"
ItemsSource="{Binding Path=Ufps, Mode=OneWay}"
ItemTemplate="{StaticResource Ufps}">
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Element"
cal:Message.Attach="[Event Click] = [Action AddElement(TrvUfpsDictionary.SelectedItem)]"
/>
................
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
........
<Button Content="Test" Canvas.Left="475" Canvas.Top="568" Width="75"
cal:Message.Attach="[Event Click] = [Action AddElement(TrvUfpsDictionary.SelectedItem)]"/>
这是简单的ViewModel代码:
public class UserSettingsViewModel : PropertyChangedBase
{
..........
public void AddElement(object selectedItem)
{
MessageBox.Show("Element added! "+selectedItem.?GetHashCode());
}
..........
}
现在,我坚持使用它。当我选择了treeview的项目,然后按下“测试”按钮时-它工作正常,它将选择的项目传递给我的VM中的“ AddElement”。但是,当我对contextmenu进行相同操作时-它始终传递null。我错过了什么吗?
编辑 我做了一个简单的应用程序,描述了问题。 https://github.com/whizzzkey/WpfApp1
答案 0 :(得分:1)
您可能必须将“上下文菜单”进一步移至TreeView,“项目模板”,然后将“上下文菜单”添加到节点中具有的Label / TextBlock。
例如,考虑下面的雇员树(由于我不知道您的数据结构,因此是模拟的),
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Positions}" >
<Label Content="{Binding DepartmentName}"/>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Employees}" >
<Label Content="{Binding PositionName}" Tag="{Binding DataContext, ElementName=TestControl}" >
<Label.ContextMenu>
<ContextMenu cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"/>
</ContextMenu>
</Label.ContextMenu>
</Label>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<Label Content="{Binding EmployeeName}" Tag="{Binding DataContext, ElementName=TestControl}">
<Label.ContextMenu>
<ContextMenu cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"
/>
</ContextMenu>
</Label.ContextMenu>
</Label>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
这里有几点要注意的要点。由于您的方法存在于ViewModel中,因此您必须确保DataContext指向的是ViewModel而不是绑定到节点的Item Type。
为此,您需要使用cal:Action.TargetWithoutContext
。标签定义的下一行确保我们可以访问视图的DataContext。
Tag="{Binding DataContext, ElementName=TestControl}"
以下行可确保我们正确绑定到ViewModel。 TestControl
是您的UserControl的x:Name
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
最后,点击操作将进行如下修改。
cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"
这将确保通过正确的参数调用ViewModel的Action。
更新
根据您的注释和代码,以下是所需的更改。
窗口定义:添加x:Name
<Window
x:Class="WpfApp1.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
Title="XmlData Tree Test"
x:Name="TestControl"
Width="250"
Height="350"
>
根分层模板 将Item来源和Tag关联起来放置在TextBlock上,相对来源也具有Self。
<HierarchicalDataTemplate DataType="root" ItemsSource="{Binding XPath=./*}" >
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0" Text="ROOT" Tag="{Binding DataContext, ElementName=TestControl}">
<TextBlock.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
节点的分层模板
<HierarchicalDataTemplate DataType="Node"
ItemsSource="{Binding XPath=./*}">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0"
Text="Node:" />
<TextBlock Margin="5,0,0,0" Tag="{Binding DataContext, ElementName=TestControl}"
Text="{Binding XPath=@name}" >
<TextBlock.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
输出示例 对于根