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

时间:2014-06-25 05:28:06

标签: c# wpf datagrid

我在WPF中使用ContextMenu,它会在MenuItem中显示发送和重新发送ContextMenu。如何使用下面代码中的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>

2 个答案:

答案 0 :(得分:2)

请在此处找到我的示例解决方案,通过添加contextmenu项及其启用/禁用代码来实现此功能。经过全面测试并提供您的功能。

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

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);
                    }
                }
            }
        }

这里我已经处理了右键单击datagridrow时打开的contextmenu。您可以将其更改为任何鼠标事件,例如previewmousebuttondown,previewmouserightbuttondown ..您只需要在xaml中进行相关更改以处理特定事件。

请将其标记为解决方案..如果它确实对您有帮助。 如果有任何疑问或疑问。请让我知道

只需创建新功能并在各自的文件中添加上面的xaml和xaml.cs,您就会更好地了解此代码实际执行的操作

当你只有少量的上下文菜单项时,上面的代码是可行的。当menuitems更多时,不建议做上面的代码。

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

答案 1 :(得分:0)

我会将此作为答案发布,因为您希望代码可能按原样运行,但我现在没有测试方法。如果不应该,我会稍后再检查并相应更正。最简单的(虽然不是MVVM,如果你使用的话)方式是在Click的{​​{1}}处理程序中执行以下操作:

MenuItem

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"/> 定义中为Opened事件添加处理程序,例如

ContextMenu

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

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