WPF: отображение контекстного меню для объектов GridView

В моих проектах я указываю профиль с опцией VM: -Dspring.profiles.active = local

Затем у меня есть файл с именем application-local.yml

в производстве: -Dspring.profiles.active = prod, будет использовать файл application-prod.yml

19
задан Community 23 May 2017 в 10:31
поделиться

2 ответа

Yes, add a ListView.ItemContainerStyle with the Context Menu.

<ListView>
  <ListView.Resources>
    <ContextMenu x:Key="ItemContextMenu">
      ...
    </ContextMenu>
  </ListView.Resources>
  <ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
      <EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnListViewItem_PreviewMouseLeftButtonDown" />
      <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}"/>
    </Style>
  </ListView.ItemContainerStyle>
</ListView>

NOTE: You need to reference the ContextMenu as a resource and cannot define it locally.

This will enable the context menu for the entire row. :)

Also see that I handle the PreviewMouseLeftButtonDown event so I can ensure the item is focused (and is the currently selected item when you query the ListView). I found that I had to this when changing focus between applications, this may not be true in your case.

Updated

In the code behind file you need to walk-up the visual tree to find the list container item as the original source of the event can be an element of the item template (e.g. a stackpanel).

void OnListViewItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
  if (e.Handled)
    return;

  ListViewItem item = MyVisualTreeHelper.FindParent<ListViewItem>((DependencyObject)e.OriginalSource);
  if (item == null)
    return;

  if (item.Focusable && !item.IsFocused)
    item.Focus();
}

The MyVisualTreeHelper that is use a wrapper that I've written to quickly walk the visual tree. A subset is posted below.

public static class MyVisualTreeHelper
{
  static bool AlwaysTrue<T>(T obj) { return true; }

  /// <summary>
  /// Finds a parent of a given item on the visual tree. If the element is a ContentElement or FrameworkElement 
  /// it will use the logical tree to jump the gap.
  /// If not matching item can be found, a null reference is returned.
  /// </summary>
  /// <typeparam name="T">The type of the element to be found</typeparam>
  /// <param name="child">A direct or indirect child of the wanted item.</param>
  /// <returns>The first parent item that matches the submitted type parameter. If not matching item can be found, a null reference is returned.</returns>
  public static T FindParent<T>(DependencyObject child) where T : DependencyObject
  {
    return FindParent<T>(child, AlwaysTrue<T>);
  }

  public static T FindParent<T>(DependencyObject child, Predicate<T> predicate) where T : DependencyObject
  {
    DependencyObject parent = GetParent(child);
    if (parent == null)
      return null;

    // check if the parent matches the type and predicate we're looking for
    if ((parent is T) && (predicate((T)parent)))
      return parent as T;
    else
      return FindParent<T>(parent);
  }

  static DependencyObject GetParent(DependencyObject child)
  {
    DependencyObject parent = null;
    if (child is Visual || child is Visual3D)
      parent = VisualTreeHelper.GetParent(child);

    // if fails to find a parent via the visual tree, try to logical tree.
    return parent ?? LogicalTreeHelper.GetParent(child);
  }
}

I hope this additional information helps.

Dennis

20
ответ дан 30 November 2019 в 03:59
поделиться

Возможно, вас заинтересуют ответы на этот вопрос SO - У меня был тот же вопрос, но я не был удовлетворен использованием события mousedown для захвата элемента, на который был щелкен на. Несколько человек ответили простыми и понятными решениями, которые могут вас заинтересовать.

Резюме: вы можете использовать контекст данных для передачи элемента обработчику или команду + команду для настройки параметров.

3
ответ дан 30 November 2019 в 03:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: