2010-10-28 3 views
0

Я определил DataGrid, как это ::
Отключить контекстное меню на некоторые клетки DatGrid WPF

<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> 

Это показывает Контекстный на каждую клетку, когда правая кнопка мыши делается.
Я хочу отключить контекстное меню для всех ячеек, кроме заголовков, а также заголовка для некоторого состояния. (я не хочу использовать DataGridHeaderStyle из-за некоторых других проблем, которые я не хочу, чтобы объяснить здесь.)

Я определил обработчик 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!!!! 
     } 
    } 

Я хочу знать, где я иду не так! Пожалуйста, помогите мне в этом. Кроме того, руководство меня сделать в лучшую сторону, если я достичь моего требования в неправильном направлении :)

ответ

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 
    } 
} 
+0

Я использовал этот ответ в качестве основы для остановки контекстного меню, отображаемого в заголовках. Спасибо, что опубликовали окончательное решение. – coffeecoder

+0

Что такое dg здесь..и как это можно назвать? .. – Silver

1

Я думаю, эта версия работает быстрее, и вам не нужно устанавливать видимость контекстного меню. Просто отмените событие click, если щелчок находился в заголовке столбца.

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; 
    } 
} 
+0

Единственная версия, которая работает для меня, если я использую этот код в событии OnMouseRIghtButtonUp. – KCT

0

У меня есть RichTextBox в DataGridCell, который не является элементом 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

-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 

К сожалению. Первый аттач был не очень хорош.