WPF中DelegateCommand无法接收ContextMenu的CommandParameter问题求助
ContextMenu在WPF中是独立于主视觉树的Popup元素,这就导致你用ElementName或RelativeSource查找祖先Button的绑定方式完全失效——绑定找不到目标元素,自然传递的参数就是null。
下面是两种可行的解决方案:
方案1:利用ContextMenu的PlacementTarget属性绑定
ContextMenu的PlacementTarget属性指向它所附着的控件(也就是你的Button),直接通过这个属性绑定即可获取Button的Name:
<Button x:Name="MyButtonName"> <!-- 省略其他代码 --> <Button.ContextMenu> <ContextMenu> <MenuItem x:Name="SomeMenuAction"> <b:Interaction.Triggers> <b:EventTrigger EventName="Click"> <b:InvokeCommandAction Command="{Binding Path=MyDelegateCommand}" CommandParameter="{Binding PlacementTarget.Name, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/> </b:EventTrigger> </b:Interaction.Triggers> </MenuItem> </ContextMenu> </Button.ContextMenu> </Button>
方案2:传递Button的DataContext给ContextMenu
如果你的ViewModel是设置在Button的DataContext上,可以先将ContextMenu的DataContext绑定到Button的DataContext,再通过PlacementTarget获取参数:
<Button x:Name="MyButtonName"> <!-- 省略其他代码 --> <Button.ContextMenu> <!-- 先把ContextMenu的DataContext绑定到Button的DataContext --> <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"> <MenuItem x:Name="SomeMenuAction"> <b:Interaction.Triggers> <b:EventTrigger EventName="Click"> <b:InvokeCommandAction Command="{Binding MyDelegateCommand}" CommandParameter="{Binding PlacementTarget.Name, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/> </b:EventTrigger> </b:Interaction.Triggers> </MenuItem> </ContextMenu> </Button.ContextMenu> </Button>
额外提示
你当前的Name是普通CLR属性,如果后续需要动态更新这个值并让绑定感知到变化,建议将其改为依赖属性:
public partial class WorkspaceButton : Button { public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(WorkspaceButton)); public string Name { get => (string)GetValue(NameProperty); set => SetValue(NameProperty, value); } public WorkspaceButton(string name) { InitializeComponent(); if (!string.IsNullOrEmpty(name)) Name = name; } }
内容的提问来源于stack exchange,提问作者roccaforte
相关产品推荐
相关产品推荐

