Доступ к информации ListViewItem из MenuItem в ContextMenu - PullRequest
1 голос
/ 14 февраля 2020

У меня есть ListView с несколькими элементами. Я хотел бы скопировать в системный буфер обмена информацию, связанную с данной строкой (например, идентификатор элемента в этой строке).

Я создал ContextMenu, которое открывается при щелчке правой кнопкой мыши по строке и отображает MenuItem для копирования идентификатора:

<ListView x:Name="MyListView" MouseDoubleClick="MyListView_MouseDoubleClick">
    <ListView.Columns>
        <GridViewColumn Header="Id" DisplayMemberBinding="{Binding MyItem.Id}"/>
    </ListView.Columns>
    <ListView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type mynamespace:MyItemDefinition}" ItemsSource="{Binding MyGroupOfItems, Mode=OneWay}" />
    </ListView.ItemTemplate>
    <ListView.ContextMenu>
        <ContextMenu>
            <MenuItem x:Name="MenuItemCopyId" Header="Copy ID" Click="MenuItemCopyId_Click"/>
        </ContextMenu>
    </ListView.ContextMenu>
</ListView>

и

private void MenuItemCopyId_Click(object sender, RoutedEventArgs e)
{
     var menu_item = ((System.Windows.Controls.MenuItem)sender);
}

Для чего Я прочитал ( Контекстное меню ListViewItem Получить данные из ListViewItem ), которое необходимо для доступа к DataContext элемента. Что может быть достигнуто с помощью PlacementTarget ContextMenu, но я не могу это сделать. Есть предложения?

Заранее спасибо

1 Ответ

2 голосов
/ 15 февраля 2020

Вы можете часто использовать PlacementTarget для выполнения некоторого относительного связывания и давать ContextMenu информацию, которой обычно не обладаете, потому что она находится за пределами визуального дерева. Учитывая то, как у вас все настроено, я не уверен, что это сработает для вас. Похоже, вам нужно контекстное меню, которое принадлежит ListView, но работает в строке, по которой щелкают правой кнопкой мыши. Вы можете сделать это вручную, добавив DataContext в событие ContextOpening. Например, я свободно следовал тому, что вы должны были установить ListView

<ListView ItemsSource="{Binding MyGroupOfItems}">
    <ListView.Resources>
        <Style TargetType="ListViewItem">
            <EventSetter Event="ContextMenuOpening" Handler="ListViewItem_ContextMenuOpening" />
        </Style>
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" />
        </GridView>
    </ListView.View>
    <ListView.ContextMenu>
        <ContextMenu Name="menu">
            <MenuItem Header="Copy ID" Click="MenuItem_Click" />
        </ContextMenu>
    </ListView.ContextMenu>
</ListView>

Я добавил стиль для ListViewItem, который обрабатывает ContextMenuOpening события. Это позволит вам узнать, какую строку вы закончились, когда открывается контекстное меню. В приведенном ниже коде вы можете прикрепить DataContext для этой строки.

private void ListViewItem_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
    ListViewItem listItem = sender as ListViewItem;
    menu.DataContext = listItem.DataContext;
}

В этом случае меню - это имя ContextMenu. Я просто беру DataContext из ListItemView и присоединяю его к ContextMenu.

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

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    MyItem item = (MyItem)(sender as MenuItem).DataContext;
    //Now you can do stuff with MyItem
}

Просто примечание: я пропустил то, что вы делали с HierarchicalDataTemplate, потому что я не понимал намерения, и для меня это ничего не вызывало. В любом случае, эта стратегия для прикрепления DataContext при открытии ContextMenu должна быть перенесена в другие варианты использования.

...