3 回答
TA贡献1827条经验 获得超7个赞
我找到了一个更简单的解决方案。
在UserControl背后的代码中:
NameScope.SetNameScope(contextMenu, NameScope.GetNameScope(this));
TA贡献1735条经验 获得超5个赞
正如其他人所说,'ContextMenu'不包含在可视树中,'ElementName'绑定不起作用。如果在“DataTemplate”中未定义上下文菜单,则仅按接受的答案建议设置上下文菜单的“NameScope”。我通过使用类似于'ElementName'绑定的{x:Reference}标记扩展来解决这个问题,但绕过可视树以不同方式解析绑定。我认为这比使用'PlacementTarget'更具可读性。这是一个例子:
<Image Source="{Binding Image}">
<Image.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding Source={x:Reference Name=Root}, Path=DataContext.RemoveImage}"
CommandParameter="{Binding}" />
</ContextMenu>
</Image.ContextMenu>
</Image>
根据MSDN文档
x:Reference是在XAML 2009中定义的构造。在WPF中,您可以使用XAML 2009功能,但仅适用于非WPF标记编译的XAML。标记编译的XAML和BAML形式的XAML目前不支持XAML 2009语言关键字和功能。
无论那意味着什么......但对我而言。
TA贡献1793条经验 获得超6个赞
这是另一个仅限xaml的解决方法。(这也假设你想要DataContext中的内容,例如,你是MVVM的)
选项一,其中ContextMenu的父元素不在DataTemplate中:
Command="{Binding PlacementTarget.DataContext.MyCommand,
RelativeSource={RelativeSource AncestorType=ContextMenu}}"
这对OP的问题很有用。如果您在DataTemplate中,这将不起作用。在这些情况下,DataContext通常是集合中的众多元素之一,并且您希望绑定的ICommand是同一ViewModel(例如Window 的DataContext)中集合的兄弟属性。
在这些情况下,您可以利用Tag暂时保存包含集合和ICommand 的父DataContext:
class ViewModel
{
public ObservableCollection<Derp> Derps { get;set;}
public ICommand DeleteDerp {get; set;}
}
并在xaml
<!-- ItemsSource binds to Derps in the DataContext -->
<StackPanel
Tag="{Binding DataContext, ElementName=root}">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem
Header="Derp"
Command="{Binding PlacementTarget.Tag.DeleteDerp,
RelativeSource={RelativeSource
AncestorType=ContextMenu}}"
CommandParameter="{Binding PlacementTarget.DataContext,
RelativeSource={RelativeSource AncestorType=ContextMenu}}">
</MenuItem>
- 3 回答
- 0 关注
- 664 浏览
添加回答
举报