![](/img/trans.png)
[英]How do I properly bind the CommandParameter with my ContextMenu to the selected ListViewItem
[英]How do I properly bind my ContextMenu command to a RelayCommand?
所以我有几个按钮设置为RelayCommand
并且它运行良好,但是当尝试绑定ContextMenu Menu Item
的Command
属性时,它只是没有反应。 我读了一些关于必须设置级别的 AncestorType 或其他内容的内容,但这是一个非常广泛的描述,没有解释原因或方式。
所以我有我的 ListView
<ListView x:Name="PlayerListView"
Width="200"
Height="330"
VerticalAlignment="Top"
Margin="0,80,15,0"
HorizontalAlignment="Right"
Background="#252525"
VerticalContentAlignment="Center"
ItemsSource="{Binding ServerViewModel.Players}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Width="190"
Background="#222222">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Command One">
<MenuItem.Icon>
<Image Source="../../Assets/image.png"
RenderOptions.BitmapScalingMode="Fant"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Command Two"
Command="{Binding ServerViewModel.MyCommand,
RelativeSource={RelativeSource AncestorType=ListViewItem}}">
<MenuItem.Icon>
<Image Source="../../Assets/image.png"
RenderOptions.BitmapScalingMode="Fant"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</StackPanel.ContextMenu>
<Image Source="../../Assets/image.png"
Width="20"
Height="20"/>
<TextBlock Text="{Binding Username}"
Foreground="White"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Margin="5"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
正如你在第二个项目中看到的,我试图将它绑定到我的 RelayCommand。 它应该可以工作,因为为我的按钮正确设置了视图模型和数据上下文。
public class BaseViewModel : ObservableObject
{
public ServerViewModel ServerViewModel { get; set; } = new ServerViewModel();
}
视图模型
public RelayCommand MyCommand { get; set; }
public ServerViewModel()
{
MyCommand = new RelayCommand(DoSomething);
}
public void DoSomething(object parameter)
{
MessageBox.Show("Working!");
}
当然还有 RelayCommand 本身。 RelayCommands 同样适用于按钮,但不适用于 ContextMenu Items
public class RelayCommand : ObservableObject, ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentException("execute");
_execute = execute;
_canExecute = canExecute;
}
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
这就是我设置 DataContext 的地方
public MainWindow()
{
InitializeComponent();
DataContext = new BaseViewModel();
}
这段代码
Command="{Binding ServerViewModel.MyCommand, RelativeSource={RelativeSource AncestorType=ListViewItem}}"
尝试在 ListViewItem 类中查找属性 ServerViewModel 并且不会找到它。 如果 ServerViewModel.Players 返回的对象本身就是 ViewModel 对象,您可以删除 RelativeSource 部分并将您的命令添加到 Player ViewModel。
例子:
Command="{Binding MyCommand}"
在 PlayerViewModel 中:
public RelayCommand MyCommand { get; set; }
public PlayerViewModel()
{
MyCommand = new RelayCommand(DoSomething);
}
public void DoSomething(object parameter)
{
MessageBox.Show("Player Working!");
}
有关替代解决方案,请参见此处: WPF:将 ContextMenu 绑定到 MVVM 命令
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.