[英]How do I add a command to items in dynamically generated ContextMenu
我有一个从ObservableCollection填充的上下文菜单。 我希望用户能够单击这些项中的任何项,然后调用一种方法来传递被单击项的文本作为参数。
我首先关注这个问题的答案。 但是,我的控制台输出中出现错误,并且未调用我的方法。
System.Windows.Data错误:40:BindingExpression路径错误:在'object''MenuItem'(Name ='myMenu')'上找不到'FunctionToCall'属性。 BindingExpression:Path = FunctionToCall; DataItem ='MenuItem'(Name ='myMenu'); 目标元素是'MenuItem'(Name =''); 目标属性为“命令”(类型为“ ICommand”)
这是我的xaml
<MenuItem Name="myMenu" Header="display text" ItemsSource="{Binding}" >
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding FunctionToCall, RelativeSource={RelativeSource AncestorType=MenuItem}}"/>
<Setter Property="CommandParameter" Value="{Binding}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
而我的视图模型代码
RelayCommand _command;
public ICommand FunctionToCall
{
get
{
if (_command == null)
{
_command = new RelayCommand(p => this.InnerMethod(p));
}
return _command ;
}
}
public void InnerMethod(object parameter)
{
....
另一个答案建议在绑定中添加一个或两个DataContext,我尝试了这个尝试,但仍然收到相同的错误,尽管它说找不到DataContext属性而不是FunctionToCall。
我在这里找到了RelayCommand的定义。
真正的问题在于绑定。 使用MenuItem的DataContext属性实际获取ViewModel实例
<MenuItem Name="myMenu" Header="display text" ItemsSource="{Binding}" >
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding DataContext.FunctionToCall, RelativeSource={RelativeSource AncestorType=MenuItem}}"/>
<Setter Property="CommandParameter" Value="{Binding}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
MenuItem将获得ViewModel作为DataContext。 所以实际上我们想要..
MenuItem.DataContext.FunctionToCall
希望您不需要将不同的菜单项绑定到不同的命令,否则您需要进行一些更改。
根据您的评论:
您需要一个List<MenuItem> MenuItems
来与ContextMenu ItemSource属性绑定为
public class MenuItem
{
public string Header { get; set; }
public ICommand Command { get; set; }
}
XAML:
<ContextMenu ItemsSource="{Binding MenuItems}" >
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}" >
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="Command" Value="{Binding Command}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
并根据需要在ViewModel中添加所需的上下文菜单项。
这是怎么做的。
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
a
<MenuItem Header="{Binding Item1}" Command="{Binding FunctionToCall}" CommandParameter="{Binding Header, RelativeSource={RelativeSource Self}}"/>
视图模型
public class ViewModel
{
ICommand _cmd = new CustomCommand();
public ICommand FunctionToCall
{
get { return _cmd; }
set { _cmd = value; }
}
public string Item1 { get; set; }
public ViewModel() { Item1 = "1Header"; }
}
命令
public class CustomCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
MessageBox.Show(parameter.ToString());
}
}
因此,假设您想将MenuItem
Header
作为参数传递给命令,请进行以下更改:
<Setter Property="Command" Value="{Binding FunctionToCall}"/>
<Setter Property="CommandParameter" Value="{Binding Header, RelativeSource={RelativeSource Self}}"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.