来自 Resources ContextMenu 的命令不会触发
Command from Resources ContextMenu does not trigger
我需要使用上下文菜单重新启动基于数据网格的服务(上下文菜单应将服务名称作为命令参数发送)
ContextMenu 正确显示,但单击 MenuItems 不会触发命令(未到达断点),但是将上下文菜单直接设置为复选框等可以完美触发命令。
最终,我想要的是在右键单击数据网格的任何项目时获得上下文菜单,单击菜单项应该将 Name 列值或整个选定项目发送到 ViewModel 中的命令(然后重新启动从那里开始的过程)。
真是头疼了几天,有什么指点...
我的数据网格:
<DataGrid x:Name="dgServices" HorizontalAlignment="Left" VerticalAlignment="Top" DockPanel.Dock="Top" Height="auto" HeadersVisibility="Row"
AutoGenerateColumns="False" HorizontalGridLinesBrush="#FFC7E0EE" VerticalGridLinesBrush="#FFC7E0EE" SelectionMode="Single" BorderThickness="0"
ItemContainerStyle="{StaticResource DefaultRowStyle}" ItemsSource="{Binding Source={StaticResource cvsServ}}">
<DataGrid.GroupStyle>
//GROUPSTYLE
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Width="30"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="373">
</DataGridTextColumn>
<DataGridTextColumn Header="Status" Binding="{Binding Status}" Width="356"/>
</DataGrid.Columns>
</DataGrid>
Window.Resources 中的 ContainerStyle 和 ContextMenu :
<Window.Resources>
<ContextMenu x:Key="RowMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="NULL" Command="{Binding restartService}"/>
<MenuItem Header="NAME" CommandParameter="{Binding PlacementTarget.Name, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
<MenuItem Header="ITEM" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
<MenuItem Header="ITEMS" CommandParameter="{Binding PlacementTarget.SelectedItems, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
</ContextMenu>
<Style x:Key="DefaultRowStyle" TargetType="{x:Type DataGridRow}">
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
<CollectionViewSource x:Key="cvsServ" Source="{Binding services, UpdateSourceTrigger=PropertyChanged}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Key" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
用于测试的复选框:
<CheckBox IsChecked="{Binding autoStart, Mode=TwoWay}">
<Label Content="AutoStart"/>
<CheckBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Edit" CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
<!--<MenuItem Header="Edit" CommandParameter="{Binding ElementName=dgServices, Path=SelectedItem}" Command="{Binding restartService}"/>-->
</ContextMenu>
</CheckBox.ContextMenu>
</CheckBox>
视图模型:
private DelegateCommand _restartService;
public DelegateCommand restartService
{
get
{
return _restartService ?? (_restartService = new DelegateCommand(o => TestCommand(o), o => true));
//return _restartService ?? (_restartService = new DelegateCommand(o => MessageBox.Show($"{o.ToString()}\n{o.GetType()}"), o => true));
//return _restartService ?? (_restartService = new DelegateCommand(o => Process.Start(new ProcessStartInfo("C:\Windows\system32\cmd.exe", "/c net start "+o.ToString()) { Verb = "runas" }), o => true));
}
private void TestCommand(object o)
{
MessageBox.Show(o?.GetType()?.ToString() ?? "NULL");
}
如果在 DataGrid
的视图模型中定义了命令 属性,您可以将行的 Tag
属性 绑定到 DataGrid
:
<Style x:Key="DefaultRowStyle" TargetType="{x:Type DataGridRow}">
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}" />
</Style>
...然后试试这个:
<MenuItem Header="NAME"
Command="{Binding PlacementTarget.Tag.DataContext.restartService, RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}"
CommandParameter="{Binding PlacementTarget.Tag.Name, RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}"/>
我需要使用上下文菜单重新启动基于数据网格的服务(上下文菜单应将服务名称作为命令参数发送)
ContextMenu 正确显示,但单击 MenuItems 不会触发命令(未到达断点),但是将上下文菜单直接设置为复选框等可以完美触发命令。
最终,我想要的是在右键单击数据网格的任何项目时获得上下文菜单,单击菜单项应该将 Name 列值或整个选定项目发送到 ViewModel 中的命令(然后重新启动从那里开始的过程)。
真是头疼了几天,有什么指点...
我的数据网格:
<DataGrid x:Name="dgServices" HorizontalAlignment="Left" VerticalAlignment="Top" DockPanel.Dock="Top" Height="auto" HeadersVisibility="Row"
AutoGenerateColumns="False" HorizontalGridLinesBrush="#FFC7E0EE" VerticalGridLinesBrush="#FFC7E0EE" SelectionMode="Single" BorderThickness="0"
ItemContainerStyle="{StaticResource DefaultRowStyle}" ItemsSource="{Binding Source={StaticResource cvsServ}}">
<DataGrid.GroupStyle>
//GROUPSTYLE
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Width="30"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="373">
</DataGridTextColumn>
<DataGridTextColumn Header="Status" Binding="{Binding Status}" Width="356"/>
</DataGrid.Columns>
</DataGrid>
Window.Resources 中的 ContainerStyle 和 ContextMenu :
<Window.Resources>
<ContextMenu x:Key="RowMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="NULL" Command="{Binding restartService}"/>
<MenuItem Header="NAME" CommandParameter="{Binding PlacementTarget.Name, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
<MenuItem Header="ITEM" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
<MenuItem Header="ITEMS" CommandParameter="{Binding PlacementTarget.SelectedItems, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
</ContextMenu>
<Style x:Key="DefaultRowStyle" TargetType="{x:Type DataGridRow}">
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
<CollectionViewSource x:Key="cvsServ" Source="{Binding services, UpdateSourceTrigger=PropertyChanged}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Key" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
用于测试的复选框:
<CheckBox IsChecked="{Binding autoStart, Mode=TwoWay}">
<Label Content="AutoStart"/>
<CheckBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Edit" CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor,AncestorType=ContextMenu}}" Command="{Binding restartService}"/>
<!--<MenuItem Header="Edit" CommandParameter="{Binding ElementName=dgServices, Path=SelectedItem}" Command="{Binding restartService}"/>-->
</ContextMenu>
</CheckBox.ContextMenu>
</CheckBox>
视图模型:
private DelegateCommand _restartService;
public DelegateCommand restartService
{
get
{
return _restartService ?? (_restartService = new DelegateCommand(o => TestCommand(o), o => true));
//return _restartService ?? (_restartService = new DelegateCommand(o => MessageBox.Show($"{o.ToString()}\n{o.GetType()}"), o => true));
//return _restartService ?? (_restartService = new DelegateCommand(o => Process.Start(new ProcessStartInfo("C:\Windows\system32\cmd.exe", "/c net start "+o.ToString()) { Verb = "runas" }), o => true));
}
private void TestCommand(object o)
{
MessageBox.Show(o?.GetType()?.ToString() ?? "NULL");
}
如果在 DataGrid
的视图模型中定义了命令 属性,您可以将行的 Tag
属性 绑定到 DataGrid
:
<Style x:Key="DefaultRowStyle" TargetType="{x:Type DataGridRow}">
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}" />
</Style>
...然后试试这个:
<MenuItem Header="NAME"
Command="{Binding PlacementTarget.Tag.DataContext.restartService, RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}"
CommandParameter="{Binding PlacementTarget.Tag.Name, RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}"/>