【发布时间】:2019-11-18 10:59:06
【问题描述】:
我需要使用上下文菜单来重新启动基于数据网格的服务(上下文菜单应该将服务的名称作为命令参数发送)
ContextMenu 正确显示,但单击 MenuItems 不会触发命令(未到达断点),而是将上下文菜单直接设置为复选框,例如完美触发命令。
最终,我想要的是在右键单击数据网格的任何项目时获取上下文菜单,单击菜单项应将名称列值或整个选定项目发送到 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");
}
【问题讨论】:
-
您的命令是否在与
services集合相同的 ViewModel 中定义?还是在表示services集合中的单独项目的视图模型中? -
试试这个:
<MenuItem Header="NAME" Command="{Binding PlacementTarget.DataContext.restartService, RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}"/> -
@mm8 这个也没有触发命令,是不是故意漏掉了命令参数?
-
@PavelAnikhouski 是的,该命令与收集服务在同一视图模型中定义
-
@Phoque:
PlacementTarget.Type是什么?Type属性在哪里定义?
标签: c# wpf mvvm command contextmenu