I was recently asked how to associate a context menu with a control in WPF. This was such a trivial request that I knocked together my favourite sample app with a context menu in it.
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="ListViewContextSample.Window1" x:Name="Window" Title="Window1" Width="640" Height="480"> <Window.Resources> <XmlDataProvider x:Key="WPFRSSFeed" d:IsDataSource="True" Source="http://www.codeproject.com/WebServices/MessageRSS.aspx?fid=1004114"/> <DataTemplate x:Key="itemTemplate"> <StackPanel> <TextBlock Text="{Binding Mode=OneWay, XPath=title}"/> <TextBlock Text="{Binding Mode=OneWay, XPath=description}"/> <TextBlock Text="{Binding Mode=OneWay, XPath=link}"/> <TextBlock Text="{Binding Mode=OneWay, XPath=author}"/> <TextBlock Text="{Binding Mode=OneWay, XPath=pubDate}"/> <TextBlock Text="{Binding Mode=OneWay, XPath=subject}"/> </StackPanel> </DataTemplate> </Window.Resources> <StackPanel x:Name="LayoutRoot"> <ScrollViewer IsTabStop="True" > <ItemsControl ItemTemplate="{DynamicResource itemTemplate}" ItemsSource="{Binding Mode=Default, Source={StaticResource WPFRSSFeed}, XPath=/rss/channel/item}"> <ItemsControl.ContextMenu> <ContextMenu Name="MyContextMenu"> <MenuItem Header="This is my menu" /> </ContextMenu> </ItemsControl.ContextMenu> </ItemsControl> </ScrollViewer> </StackPanel> </Window>
As you can see, we have a simple RSS reader associated with a context menu. Now, I chose to explicitly create this menu in the ItemsControl.ContextMenu because we only need to use it once.
The same person then stated that what they actually wanted was to associate a context menu with an item in a ListBox, but not the listbox itself. This was just too good an opportunity to pass up to demonstrate how powerful WPF really is. In the following sample, I’ve created a context menu as a resource which is associated with an item in the listbox. Because the ListBoxItem content is exposed for you to manipulate, I’ve associate the context menu with a TextBlock. I could have associated it with the ListBoxItem itself, but I wanted to demonstrate that you can put different types of items in the Content here (you could put an image in if you wanted, for instance).
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="ListViewContextSample.Window1" x:Name="Window" Title="Window1" Width="640" Height="480"> <Window.Resources> <ContextMenu x:Key="MyMenu"> <MenuItem Header="Send" /> </ContextMenu> </Window.Resources> <Grid> <ListBox Height="70" VerticalAlignment="Top"> <ListBoxItem> <ListBoxItem.Content> <TextBlock Text="My Listbox item" ContextMenu="{StaticResource MyMenu}" /> </ListBoxItem.Content> </ListBoxItem> </ListBox> </Grid> </Window>



November 6, 2008 at 9:17 am |
What if the list box is databind with a collection? How would we then attach the context menu with the list box item ?
November 6, 2008 at 12:02 pm |
Irfan
You would associate it with the ListBoxItem, for instance:
<ListBoxItem ContextMenu = “{StaticResource MyMenu}” >
November 6, 2008 at 1:18 pm |
I think you didn’t get my point. Here is a sample code where I need to attach a context menu to each item.
XAML code :
C# Code Behind:
private ObservableCollection itemsList = new ObservableCollection();
public MyClass()
{
InitializeComponent();
// Data bind items list to list box
lbItems.ItemsSource = itemsList;
}
Now here the list box item source is set at run time rather than hardcoding like . So my question is how to associate a context menu with the items that it picks from the collection.