禁用某些DataGrid单元格WPF上的上下文菜单

时间:2010-10-28 05:36:17

标签: wpf datagrid contextmenu datagridcell

我已经定义了一个像这样的数据网格::

 <cc:PEDataGrid AutoGenerateColumns="False"
               ItemsSource="{Binding Rows}"
               Width="Auto"                
               PreviewMouseRightButtonDown="PEGrid_PreviewMouseRightButtonDown"
               Loaded="CommonPEGrid_Loaded">             
      <wpfkit:DataGrid.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Cut" />
            <MenuItem Header="Copy"/>
            <MenuItem Header="Paste"/>              
        </ContextMenu>
    </wpfkit:DataGrid.ContextMenu>
</cc:PEDataGrid>

这显示右键单击完成后每个单元格上的contextMenu。
我想为除标题之外的所有单元格以及某些条件的标题上禁用上下文菜单(我不想使用DataGridHeaderStyle,因为其他一些我不想在这里解释的问题。)

我已经在datagrid和处理程序中为PreviewMouseRightButtonDown定义了一个处理程序我试图做这样的事情::

    private void PEGrid_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject depObj = (DependencyObject)e.OriginalSource;

        while ((depObj != null) && !(depObj is DataGridColumnHeader))
        {
            depObj = VisualTreeHelper.GetParent(depObj);
        }

        if (depObj == null)
        {
            return;
        }

        if (depObj is DataGridColumnHeader)
        {
            //some condition here which says whether contextmenu is required on this header

            (depObj as DataGridColumnHeader).ContextMenu = null;
            //the above line is not working!!!!
        }
        else
        {
             (depObj as DataGridCell).ContextMenu = null;
              //the above line not working!!!!
         }
    }

我想知道我哪里错了!!请帮我解决这个问题。如果我以错误的方式达到我的要求,也指导我以更好的方式做:)

4 个答案:

答案 0 :(得分:1)

嘿我解决了::我的修改后的代码如下:::

private void PEGrid_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    DependencyObject depObj = (DependencyObject)e.OriginalSource;

    while ((depObj != null) && !(depObj is DataGridColumnHeader))
    {
        depObj = VisualTreeHelper.GetParent(depObj);
    }

    if (depObj == null)
    {
        return;
    }

    if (depObj is DataGridColumnHeader)
    {
          dg.ContextMenu.Visibility = Visibility.Visible;  //works
    }
    else
    {
          dg.ContextMenu.Visibility = Visibility.Collapsed; //works
     }
}

答案 1 :(得分:1)

我认为此版本更快,您无需设置上下文菜单的可见性。如果点击位于列标题上,只需取消点击事件。

private void PEGrid_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    var depObj = (DependencyObject)e.OriginalSource;
    while ((depObj != null) && !(depObj is DataGridColumnHeader))
    {
        depObj = VisualTreeHelper.GetParent(depObj);
    }
    if (depObj is DataGridColumnHeader)
    {
        e.Handled = true;
    }
}

答案 2 :(得分:0)

我在DataGridCell中有RichTextBox,它不是VisualTree元素。我的代码:

private void dgLog_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        FrameworkContentElement fce = e.OriginalSource as FrameworkContentElement;
        DependencyObject depObj = e.OriginalSource as DependencyObject;
        DataGridCell dgc = null;
        DataGridRow dgr = null;
        try
        {
            while (fce != null && !(fce is DataGridCell))
            {
                depObj = fce.Parent;
                fce = depObj as FrameworkContentElement;
            }
            while (depObj != null && !(depObj is DataGridRow))
            {
                if (depObj is DataGridCell)
                    dgc = depObj as DataGridCell;
                depObj = VisualTreeHelper.GetParent(depObj);
            }
            if (depObj == null)
                return;
            dgr = depObj as DataGridRow;
            if (((LogRecord)dgr.Item).SourceType == "FileMessage" && dgc.Column.DisplayIndex == 1)
                dgLog.ContextMenu = cm_dgLog;
            else
                dgLog.ContextMenu = null;
        }
        catch (Exception ex)
        {
            MessageBox.Show(...);
            TraceHelper.TraceError(ex, GetType());
        }
    }//private void dgLog_PreviewMouseRightButtonDown

LogRecord是DataGridColumn.Item的类型

答案 3 :(得分:-1)

    private void dgLog_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        FrameworkContentElement fce = e.OriginalSource as FrameworkContentElement;
        DependencyObject depObj = e.OriginalSource as DependencyObject;
        DataGridCell dgc = null;
        DataGridRow dgr = null;
        try
        {
            while (fce != null && !(fce is DataGridCell))
            {
                depObj = fce.Parent;
                fce = depObj as FrameworkContentElement;
            }
            while (depObj != null && !(depObj is DataGridRow))
            {
                if (depObj is DataGridCell)
                    dgc = depObj as DataGridCell;
                depObj = VisualTreeHelper.GetParent(depObj);
            }
            if (depObj == null)
                return;
            dgr = depObj as DataGridRow;
            if (((LogRecord)dgr.Item).SourceType == "FileMessage" && dgc.Column.DisplayIndex == 1)
                dgLog.ContextMenu = cm_dgLog;
            else
                dgLog.ContextMenu = null;
        }
        catch (Exception ex)
        {
            MessageBox.Show(...);
            TraceHelper.TraceError(ex, GetType());
        }
    }//private void dgLog_PreviewMouseRightButtonDown

对不起。第一次尝试并不是那么好。