我正在尝试使用MVVM与WPF制作一个简单的TODO应用程序。我在Datagrid和右键单击上下文菜单中的任务与删除选择。我不希望在数据网格中没有元素时显示上下文菜单。我怎么做才能解决这个问题?
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{Binding Path=TaskList}" SelectedItem="{Binding SelectedTask}" AutoGenerateColumns="False">
<DataGrid.ContextMenu >
<ContextMenu>
<MenuItem Header="Delete" Command="{Binding OpenDialogCommand}" CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"></MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Header="Priority" Width="auto" Binding="{Binding Path=Id}"/>
<DataGridTextColumn Header="Task" Width="auto" Binding="{Binding Path=TaskName}"/>
</DataGrid.Columns>
</DataGrid>
您可以使用Style
和Trigger
有条件地设置ContextMenu
属性:
<DataGrid ItemsSource="{Binding Path=TaskList}" SelectedItem="{Binding SelectedTask}" AutoGenerateColumns="False">
<DataGrid.Style>
<Style TargetType="DataGrid">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Delete" Command="{Binding OpenDialogCommand}"
CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"></MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter Property="ContextMenu" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Style>
<DataGrid.Columns>
<DataGridTextColumn Header="Priority" Width="auto" Binding="{Binding Path=Id}"/>
<DataGridTextColumn Header="Task" Width="auto" Binding="{Binding Path=TaskName}"/>
</DataGrid.Columns>
</DataGrid>
您可以绑定可见性并使用内置的布尔可见性转换器
你需要转换器。这可以在你合并到app.xaml中的资源字典中,以便在整个应用中使用。
<Window.Resources>
<BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
</Window.Resources>
然后在上下文菜单上绑定可见性
<DataGrid ...... >
<DataGrid.ContextMenu>
<ContextMenu Visibility="{Binding PlacementTarget.HasItems, RelativeSource={RelativeSource Self},
Converter={StaticResource booleanToVisibilityConverter}}">
<MenuItem Header="Delete"
Command="{Binding OpenDialogCommand}"
CommandParameter="{Binding PlacementTarget.SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu>
</DataGrid.ContextMenu>
您可以使用ContextMenuService作为一种变体。IsEnabled附加属性并与ItemsControl.HasItems
绑定。
<DataGrid ...
ContextMenuService.IsEnabled="{Binding RelativeSource={RelativeSource Self}, Path=HasItems}">
我有一个简单的技巧来解决这个问题。我将行定义从*更改为行2的auto;这将阻止上下文菜单显示,当你点击任何地方,而不是Datagrid Elements。
<RowDefinition Height="auto"/>
也删除了一个额外的行,总是显示(并显示上下文菜单时右键单击)
这工作。
<DataGrid Margin ="10" x:Name="dgTaks" Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Path=TaskList}" SelectedItem="{Binding SelectedTask}" AutoGenerateColumns="False" **CanUserAddRows="False"**>