0

私は多くの ListViews を持っており、それぞれが独自の ListCollectionView にバインドされており、それぞれが同じ ContextMenu を必要としています。同じ ContextMenu を N 回繰り返したくないので、Resources で定義し、StaticResource を介して参照します。

ListView のアイテム X が右クリックされ、MenuItem がクリックされた場合、分離コードでオブジェクト X にアクセスするにはどうすればよいですか?

<Window.Resources>
    <ContextMenu x:Key="CommonContextMenu">
        <MenuItem Header="Do Stuff" Click="DoStuff_Click" />
    </ContextMenu>
</Window.Resources>

<ListView ItemsSource="{Binding Path=ListCollectionView1}" ContextMenu="{StaticResource CommonContextMenu}">
    ...
</ListView>

<ListView ItemsSource="{Binding Path=ListCollectionView2}" ContextMenu="{StaticResource CommonContextMenu}">
    ...
</ListView>

private void DoStuff_Click(object sender, RoutedEventArgs e)
{
    // how do i get the selected item of the right listview?
}

アップデート

Michael Gunter の回答のおかげで、次の拡張メソッドを使用しています。

public static ListView GetListView(this MenuItem menuItem)
{
    if (menuItem == null)
        return null;

    var contextMenu = menuItem.Parent as ContextMenu;
    if (contextMenu == null)
        return null;

    var listViewItem = contextMenu.PlacementTarget as ListViewItem;
    if (listViewItem == null)
        return null;

    return listViewItem.GetListView();
}

public static ListView GetListView(this ListViewItem item)
{
    for (DependencyObject i = item; i != null; i = VisualTreeHelper.GetParent(i))
    {
        var listView = i as ListView;
        if (listView != null)
            return listView;
    }

    return null;
}
4

1 に答える 1

1

1) コンテキスト メニューを、各アイテム自体ListViewではなく、各アイテム内の各アイテムに配置ListViewします。これにより、 の空のスペースをクリックしたときにコンテキスト メニューがポップアップするのを回避できますListView。これを行うには、ListView.ItemContainerStyleプロパティを使用します。(コンテキストメニュー自体が本当に必要な場合はListView、お知らせください。それに応じてこの回答を編集します。)

<Window.Resources>
    <ContextMenu x:Key="CommonContextMenu">
        <MenuItem Header="Do Stuff" Click="DoStuff_Click" />
    </ContextMenu>
    <Style x:Key="ListViewItemStyle" TargetType="{x:Type ListViewItem}">
        <Setter Property="ContextMenu" Value="{StaticResource CommonContextMenu}" />
    </Style>
</Window.Resources>

<ListView ItemsSource="{Binding Path=ListCollectionView1}" ItemContainerStyle="{StaticResource ListViewItemStyle}">
    ...
</ListView>
<ListView ItemsSource="{Binding Path=ListCollectionView2}" ItemContainerStyle="{StaticResource ListViewItemStyle}">
    ...
</ListView>

2) 次のようなコードを使用して、右クリックされたアイテムを特定します。

private void DoStuff_Click(object sender, RoutedEventArgs e)
{
    var menuItem = sender as MenuItem;
    if (menuItem == null)
        return;

    var contextMenu = menuItem.Parent as ContextMenu;
    if (contextMenu == null)
        return;

    var listViewItem = contextMenu.PlacementTarget as ListViewItem;
    if (listViewItem == null)
        return;

    var listView = GetListView(listViewItem);
    if (listView == null)
        return;

    // do stuff here
}

private ListView GetListView(ListViewItem item)
{
    for (DependencyObject i = item; i != null; i = VisualTreeHelper.GetParent(i))
    {
        var listView = i as ListView;
        if (listView != null)
            return listView;
    }
    return null;
}
于 2013-07-31T21:24:37.087 に答える