我使用 Caliburn Micro 将我的分层 TreeView 完美地绑定(bind)到我的 ViewModel。 (ViewModel 有一个返回 ObservableCollection 的 Items 属性—— TreeView 被命名为这个 Items 属性——绑定(bind)没有问题)。
但是问题出现在上下文菜单中。菜单在树节点表示的对象实例上触发一个方法。我更想实现的是让菜单在我的根 ViewModel 上触发一个方法,将被单击的树节点表示的对象实例作为参数传递给它。 这是我的 XAML:
<HierarchicalDataTemplate DataType="{x:Type m:TaskGrouping}"
ItemsSource="{Binding Children}">
<Label Content="{Binding Name}"
FontWeight="Bold">
<Label.ContextMenu>
<ContextMenu>
<MenuItem Header="Add New SubFolder"
cal:Message.Attach="AddNewSubfolder" />
<MenuItem Header="Remove this folder"
cal:Message.Attach="RemoveFolder" />
</ContextMenu>
</Label.ContextMenu>
</Label>
</HierarchicalDataTemplate>
我需要对我的 XAML 进行哪些更改才能实现我想要的?
最佳答案
ContextMenus
位于独立于其他所有内容的可视化树中 - 正确设置绑定(bind)可能很痛苦(我经常需要 10-15 分钟的时间来解决它们的绑定(bind)问题,才能正确设置它们!)
您已经设置了 Message.Attach
附加属性,您需要做的就是确保操作目标指向 VM 而不是数据项。您可以使用 Action.TargetWithoutContext
指定操作的目标(否则 CM 将使用 DataContext
)
您还需要获取指向其他可视化树的绑定(bind)路径 - 尝试使用 RelativeSource
绑定(bind) - ContextMenu
也有一个名为 PlacementTarget 的属性
应该指向 ContextMenu
附加到的元素
那么可能:
cal:Action.TargetWithoutContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Label}}"
或
cal:Action.TargetWithoutContext="{Binding PlacementTarget.DataContext}"
您可能需要进行试验,因为我经常几乎第一次就做对了!
OP(Shawn)编辑: 这最终对我有用:
<Label Content="{Binding Name}"
Tag="{Binding DataContext, ElementName=LayoutRoot}">
<Label.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Run Task Now" cal:Message.Attach="SomeRootViewModelMethod($dataContext)" />
关于wpf - 带有 Treeview 上下文菜单的 Caliburn Micro,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15785987/