如何根据DataGrid中的条件启用和禁用动态上下文菜单

本文关键字:动态 菜单 上下文 启用 条件 何根 DataGrid | 更新日期: 2023-09-27 18:10:21

我在WPF中使用ContextMenu,它显示在ContextMenu中发送和重发MenuItem。我如何在下面的代码中使用SendResend菜单项来启用/禁用上下文菜单?

<DataGrid.ContextMenu>
    <ContextMenu x:Name="CMenuu"> 
        <MenuItem Name="Send" Header="Send" Click="Send_Click"/>
        <MenuItem Name="Resend" Header="Resend" Click="Resend_Click"/>
        <MenuItem Name="Report"Header="Report" Click="Report_Click"/>
    </ContextMenu>
</DataGrid.ContextMenu>

如何根据DataGrid中的条件启用和禁用动态上下文菜单

请在这里找到我的示例解决方案,通过在后面的代码中添加上下文菜单项及其启用/禁用来实现此功能。它经过了充分的测试,并为您的功能服务。

我在这里粘贴完整的示例代码

Mainwindow.xaml

<Window x:Class="yourapplicatioName.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
            <DataGrid x:Name="data1" AutoGenerateColumns="True"  ItemsSource="{Binding Path=.}"  Width="500" Height="500" PreviewMouseRightButtonDown="data1_PreviewMouseRightButtonDown_1">
            </DataGrid>
    </Grid>
</Window>

Mainwindow.xaml.cs

public MainWindow()
        {
            InitializeComponent();
            BindDataToDataGrid();
        }

        private void Send_Click_1(object sender, RoutedEventArgs e)
        {
        }
        private void Resend_Click_1(object sender, RoutedEventArgs e)
        {
        }
        private void Report_Click_1(object sender, RoutedEventArgs e)
        {
        }
        public static T FindVisualParent<T>(UIElement element) where T : UIElement
        {
            UIElement parent = element;
            while (parent != null)
            {
                T correctlyTyped = parent as T;
                if (correctlyTyped != null)
                {
                    return correctlyTyped;
                }
                parent = VisualTreeHelper.GetParent(parent) as UIElement;
            }
            return null;
        }
        private void BindDataToDataGrid()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ID");
            dt.Columns.Add("StatusCode");
            dt.Rows.Add("Kartik", "Send");
            dt.Rows.Add("Ashok", "Resend");
            dt.Rows.Add("Paresh", "Report");
            dt.AcceptChanges();
            data1.ItemsSource = dt.DefaultView;
        }
        private void data1_PreviewMouseRightButtonDown_1(object sender, MouseButtonEventArgs e)
        {
            if (e.OriginalSource.GetType() != typeof(DataGridColumnHeader))
            {
                DataGridRow dgr = FindVisualParent<DataGridRow>(e.OriginalSource as UIElement);
                if (dgr != null && dgr.Item != null)
                {
                    //here checked value of statuscode on the basis of row clicked
                    string statusCode = Convert.ToString((dgr.Item as DataRowView).Row["StatusCode"]);
                    if (statusCode == "Send")
                    {
                        MenuItem objResend = new MenuItem();
                        objResend.Header = "Resend";
                        objResend.Click += Resend_Click_1;
                        MenuItem objsend = new MenuItem();
                        objsend.Header= "Send";
                        objsend.IsEnabled = false;
                        data1.ContextMenu = new System.Windows.Controls.ContextMenu();
                        data1.ContextMenu.Items.Add(objResend);
                        data1.ContextMenu.Items.Add(objsend);
                    }
                    else if (statusCode == "Resend")
                    {
                        //on resend resend is disabled
                        MenuItem objResend = new MenuItem();
                        objResend.Header = "Resend";
                        objResend.IsEnabled = false;
                        MenuItem objsend = new MenuItem();
                        objsend.Header = "Send";
                        objsend.Click += Send_Click_1;
                        data1.ContextMenu = new System.Windows.Controls.ContextMenu();
                        data1.ContextMenu.Items.Add(objResend);
                        data1.ContextMenu.Items.Add(objsend);
                    }
                    else if (statusCode == "Report")
                    {
                        //both are enabled 
                        MenuItem objResend = new MenuItem();
                        objResend.Header = "Resend";
                        objResend.Click += Resend_Click_1;
                        MenuItem objsend = new MenuItem();
                        objsend.Header = "Send";
                        objsend.Click += Send_Click_1;
                        data1.ContextMenu = new System.Windows.Controls.ContextMenu();
                        data1.ContextMenu.Items.Add(objResend);
                        data1.ContextMenu.Items.Add(objsend);
                    }
                }
            }
        }

在这里我已经处理上下文菜单打开右键点击datagdrow。你可以将其更改为任何鼠标事件,例如previewmousebuttondown, previewmouserightbuttondown..你只需要在xaml中做一些相关的改变来处理特定的事件。

请标记为解决方案。如果它真的对你有帮助的话。如有疑问或疑问。请让我知道

只要创建新的功能,并在你各自的文件中添加上面的xaml和xaml.cs,你就会更好地了解这段代码到底在做什么

当你只有少量的上下文菜单项时,

上面的代码是可行的。当菜单项较多时,不建议使用上述代码。

在共享Skydrive位置下方的图像中查找工作代码结果:http://1drv.ms/1sJF6WQ

既然你问了,我将把这个作为答案,希望代码可以正常工作,但我现在没有测试的手段。如果不正确,我会稍后再检查并进行相应的修改。最简单的方法(如果您使用的是不尊重mvvm的)是在MenuItemClick处理程序中执行以下操作:

private void Send_Click(object sender, RoutedEventArgs e)
{
  Send.IsEnabled = false;
  Resend.IsEnabled = true;
}

private void Resend_Click(object sender, RoutedEventArgs e)
{
  Send.IsEnabled = true;
  Resend.IsEnabled = false;
}

这是"快速和肮脏",但你应该添加以下XAML标记,如果你不希望两个菜单项在开始时启用:

<MenuItem Name="Resend" Header="Resend" Click="Resend_Click" IsEnabled="False"/>

希望这对你有帮助,我正确地理解了你。

Edit:似乎还有其他的愿望。我希望这次我能成功。您可以在ContextMenu定义中为Opened事件添加处理程序,例如

<ContextMenu x:Name="cMenuu" Opened="cMenuu_Opened"> ...

然后按照下面的行做一些事情(因为你没有给出状态的代码,我只能在这里猜测):

private void cMenuu_Opened(object sender, RoutedEventArgs e)
{
  // Here, get the selected item from your grid and check the status
  var item = yourGridNameHere.SelectedItem;
  // Again: pseudo code to check the status
  if (item.Status == "reported")
  {
    Send.IsEnabled = false;
    Resend.IsEnabled = true;
  }
  else
  {
    // Something else, like enable the other menu items again
  }
}