WPF DataGrid 上下文菜单无需右键单击该行即可显示

问题描述 投票:0回答:1

WPF 应用程序有 2 种模式:基本模式和高级模式。
有一个

DataGrid
,用户可以使用上下文菜单
Rerun
Delete
当前项目。
此上下文菜单仅在高级模式处于活动状态时才可用(
Visibility
IsEnabled
绑定到
IsAdvancedMode
属性):

<DataGrid.ContextMenu>
    <ContextMenu Visibility="{Binding DataContext.IsAdvancedMode, Source={StaticResource ProxyElement}, Mode=OneWay,
      Converter={conv:BoolToVisibilityConverter VisibilityForFalse=Hidden}}"
      IsEnabled="{Binding DataContext.IsAdvancedMode, Source={StaticResource ProxyElement}, Mode=OneWay}">
.....
</DataGrid.ContextMenu>

当然,只有当用户右键单击

DataGrid
行时才会显示上下文菜单。
但当用户从基本模式切换到高级模式时(通过在应用程序的对话框之一中输入凭据),它确实会显示。
如何克服这种影响?

enter image description here

c# wpf datagrid contextmenu visibility
1个回答
0
投票

让我们跳到

如何克服这种影响?

如果我理解你的代码,你可能想要挂钩

ContextMenuOpening
DataGrid
事件,并根据
Handled
的值将其标记为
IsAdvancedMode
或不标记它。标记它
Handled
将阻止显示上下文菜单。


隐藏代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    new MainWindowDataContext DataContext =>(MainWindowDataContext)base.DataContext;

    private void ContextMenu_Opening(object sender, ContextMenuEventArgs e)
    {
        e.Handled = !DataContext.IsAdvancedMode;
    }
}
Xaml 最小可重现示例
<Window x:Class="wpf_context_menu.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:wpf_context_menu"
        xmlns:conv="clr-namespace:wpf_context_menu.Converters"
        mc:Ignorable="d"
        Title="MainWindow" Width="500" Height="300">
    <Window.Resources>
        <local:MenuDataContext x:Key="ProxyElement" />
    </Window.Resources>
    <Window.DataContext>
        <local:MainWindowDataContext />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <DataGrid
            x:Name="dataGrid"
            ItemsSource="{Binding JobItems}"
            ContextMenuOpening="ContextMenu_Opening"
            AutoGenerateColumns="False"
            FontSize="16">
            <DataGrid.ContextMenu>
                <ContextMenu
                    ItemsSource="{Binding MenuItems, Source={StaticResource ProxyElement}}" />
            </DataGrid.ContextMenu>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Job Name" Binding="{Binding JobName}" Width="*" />
                <DataGridTextColumn Header="Start Time" Binding="{Binding StartTime}" />
                <DataGridTextColumn Header="Status" Binding="{Binding Status}" />
            </DataGrid.Columns>
        </DataGrid>
        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
            <CheckBox IsChecked="{Binding IsAdvancedMode}" />
            <TextBlock Text="Is Advanced Mode" Margin="5,0,0,0" VerticalAlignment="Center" />
        </StackPanel>
    </Grid>
</Window>
数据上下文最小可重现示例
partial class MainWindowDataContext : ObservableObject
{
    [ObservableProperty]
    private bool _isAdvancedMode;
    public ObservableCollection<JobItem> JobItems { get; } = new ObservableCollection<JobItem>
    {
        new JobItem { JobName = "Data Backup", StartTime = DateTime.Now.AddMinutes(-30), Status = Status.SUCCESS },
        new JobItem { JobName = "Data Analysis", StartTime = DateTime.Now.AddMinutes(-60), Status = Status.FAILED },
        new JobItem { JobName = "Report Generation", StartTime = DateTime.Now.AddMinutes(-120), Status = Status.SUCCESS },
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.