I am using .NET Core 3.1 WPF.
Question 1. Is defining the <ContextMenu>
inside of the item template, like this one a recommended way? If, for example, there are 100 items, won't that create 100 invisible context menus?
Question 2. If it is not efficient to define the <ContextMenu>
inside of the item template, I want to avoid defining <ItemsControl.ContextMenu>
like this one, because that would show the context menu, if the user right-clicks on an empty (where there is no items) area. It seems efficient to define one <ContextMenu>
in a parent control like this, but the source code of the existing question is a little bit too complex, and I could not get it work.
Below is a simple example code. How can I get Dog
object that is bound to the StackPanel
in the context menu click event ShowBreed
?
<Window x:Class="deletewpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="600">
<ItemsControl Name="DogList">
<ItemsControl.Resources>
<ContextMenu x:Key="ItemContextMenu"
DataContext="{Binding PlacementTarget.Tag}">
<MenuItem Click="ShowBreed" CommandParameter="{Binding}" >Show Breed</MenuItem>
</ContextMenu>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel ContextMenu="{StaticResource ItemContextMenu}"
Tag="{Binding DataContext}">
<TextBlock FontSize="30pt" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
Code behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var dogs = new List<Dog>();
dogs.Add(new Dog { Name = "Dog1", Breed = "Shiba" });
dogs.Add(new Dog { Name = "Dog2", Breed = "Corgi" });
DogList.ItemsSource = dogs;
}
private void ShowBreed(object sender, RoutedEventArgs e)
{
Dog d;
//MessageBox.Show(d.Breed);
}
}
class Dog
{
public string Name { get; set; }
public string Breed { get; set; }
}