Nishant Rana's Weblog


Home | Pages | Archives


How to – Create dynamic ContextMenu for TreeView in WPF

March 13, 2012 1:18 AM


Hi,

Sharing a simple example wherein we are generating dynamic menuitems for the context menu based on the node or treeviewitem selected in the treeview.

If root Packages is selected –

If Package is selected –

If Batch is selected –

The xml file

<br />
&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />
&lt;Packages&gt;<br />
 &lt;Package Name="Package 1" Type="Package"&gt;<br />
 &lt;Batch Name="Batch 1" Type="Batch"/&gt;<br />
 &lt;Batch Name="Batch 2" Type="Batch"/&gt;<br />
 &lt;/Package&gt;<br />
 &lt;Package Name="Package 2" Type="Package"&gt;<br />
 &lt;Batch Name="Batch 1" Type="Batch"/&gt;<br />
 &lt;Batch Name="Batch 2" Type="Batch"/&gt;<br />
 &lt;/Package&gt;<br />
&lt;/Packages&gt;<br />

XAML

<br />
&lt;Window x:Class="SampleSyncServerAdminTool.MainWindow"<br />
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"<br />
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"<br />
 Title="MainWindow" Height="350" Width="525"&gt;<br />
 &lt;Window.Resources&gt;<br />
 &lt;!--Binding TreeView--&gt;<br />
 &lt;XmlDataProvider x:Key="MyList" Source="Packages.xml" XPath="Packages"/&gt;</p>
<p>&lt;HierarchicalDataTemplate DataType="Packages" ItemsSource="{Binding XPath=*}"&gt;<br />
 &lt;TextBlock Text="Packages"&gt;&lt;/TextBlock&gt;<br />
 &lt;/HierarchicalDataTemplate&gt;</p>
<p>&lt;HierarchicalDataTemplate DataType="Package" ItemsSource="{Binding XPath=*}"&gt;<br />
 &lt;TextBlock Text="{Binding XPath=@Name}"&gt;&lt;/TextBlock&gt;<br />
 &lt;/HierarchicalDataTemplate&gt;</p>
<p>&lt;HierarchicalDataTemplate DataType="Batch" ItemsSource="{Binding XPath=*}"&gt;<br />
 &lt;TextBlock Text="{Binding XPath=@Name}"&gt;&lt;/TextBlock&gt;<br />
 &lt;/HierarchicalDataTemplate&gt;</p>
<p>&lt;!-- Resources for Right Hand Side detail grid--&gt;</p>
<p>&lt;DataTemplate x:Key="ClosableTabItemTemplate"&gt;<br />
 &lt;DockPanel Width="120"&gt;<br />
 &lt;Button<br />
 Command="{Binding Path=CloseCommand}"<br />
 Content="X"<br />
 Cursor="Hand"<br />
 DockPanel.Dock="Right"<br />
 Focusable="False"<br />
 FontFamily="Courier"<br />
 FontSize="9"<br />
 FontWeight="Bold"<br />
 Margin="0,1,0,0"<br />
 Padding="0"<br />
 VerticalContentAlignment="Bottom"<br />
 Width="16" Height="16"<br />
 /&gt;<br />
 &lt;ContentPresenter<br />
 Content="{Binding Path=DisplayName}"<br />
 VerticalAlignment="Center"<br />
 /&gt;<br />
 &lt;/DockPanel&gt;<br />
 &lt;/DataTemplate&gt;</p>
<p>&lt;DataTemplate x:Key="WorkspacesTemplate"&gt;<br />
 &lt;TabControl<br />
 IsSynchronizedWithCurrentItem="True"<br />
 ItemsSource="{Binding}"<br />
 ItemTemplate="{StaticResource ClosableTabItemTemplate}"<br />
 Margin="4"<br />
 /&gt;<br />
 &lt;/DataTemplate&gt;</p>
<p>&lt;/Window.Resources&gt;<br />
 &lt;Grid&gt;<br />
 &lt;DockPanel&gt;<br />
 &lt;TreeView DockPanel.Dock="Left" Width="150" Name="treeViewPackages"</p>
<p> ItemsSource="{Binding Source={StaticResource MyList}}"&gt;<br />
 &lt;TreeView.Resources&gt;<br />
 &lt;ContextMenu x:Key="TestMenu"&gt;<br />
 &lt;/ContextMenu&gt;<br />
 &lt;/TreeView.Resources&gt;<br />
 &lt;TreeView.ItemContainerStyle&gt;<br />
 &lt;Style TargetType="{x:Type TreeViewItem}"&gt;<br />
 &lt;Setter Property="IsExpanded" Value="True"/&gt;<br />
 &lt;EventSetter Event="PreviewMouseRightButtonDown"<br />
 Handler="OnPreviewMouseRightButtonDown" /&gt;<br />
 &lt;/Style&gt; &lt;/TreeView.ItemContainerStyle&gt;<br />
 &lt;/TreeView&gt;<br />
 &lt;Grid DockPanel.Dock="Right"&gt;<br />
 &lt;HeaderedContentControl<br />
 Content="{Binding Path=Workspaces}"<br />
 ContentTemplate="{StaticResource WorkspacesTemplate}"<br />
 Header="Workspaces"<br />
 /&gt;<br />
 &lt;/Grid&gt;<br />
 &lt;/DockPanel&gt;<br />
 &lt;/Grid&gt;<br />
&lt;/Window&gt;<br />

XAML.cs

<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Text;<br />
using System.Windows;<br />
using System.Windows.Controls;<br />
using System.Windows.Data;<br />
using System.Windows.Documents;<br />
using System.Windows.Input;<br />
using System.Windows.Media;<br />
using System.Windows.Media.Imaging;<br />
using System.Windows.Navigation;<br />
using System.Windows.Shapes;<br />
using System.Xml;</p>
<p>namespace SampleSyncServerAdminTool<br />
{<br />
 /// &lt;summary&gt;<br />
 /// Interaction logic for MainWindow.xaml<br />
 /// &lt;/summary&gt;<br />
 public partial class MainWindow : Window<br />
 {<br />
 public MainWindow()<br />
 {<br />
 InitializeComponent();<br />
 }</p>
<p>void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)<br />
 {</p>
<p>DependencyObject obj = e.OriginalSource as DependencyObject;<br />
 TreeViewItem item = GetDependencyObjectFromVisualTree(obj, typeof(TreeViewItem)) as TreeViewItem;<br />
 XmlElement selectedElement = (XmlElement)item.Header;</p>
<p>string header = selectedElement.Name;<br />
 if (header.ToUpper() == "PACKAGES")<br />
 {<br />
 // Packages root node<br />
 MenuItem mnuItem = new MenuItem();<br />
 mnuItem.Header = "New Package";<br />
 ContextMenu menu = new ContextMenu() { };<br />
 menu.Items.Add(mnuItem);<br />
 (sender as TreeViewItem).ContextMenu = menu;<br />
 }</p>
<p>else<br />
 {<br />
 string attName = selectedElement.Attributes["Name"].Value;<br />
 string type = selectedElement.Attributes["Type"].Value;</p>
<p>string fullNodeInfo = "Header: " + header + " Attribute Name: " + attName + " Type: " + type;</p>
<p>if (type.ToUpper() == "PACKAGE")<br />
 {<br />
 MenuItem mnuItem1 = new MenuItem();<br />
 mnuItem1.Header = "New Package";<br />
 MenuItem mnuItem2 = new MenuItem();<br />
 mnuItem2.Header = "Show Package Details";<br />
 MenuItem mnuItem3 = new MenuItem();<br />
 mnuItem3.Header = "Edit Package";<br />
 MenuItem mnuItem4 = new MenuItem();<br />
 mnuItem4.Header = "Delete Package";<br />
 MenuItem mnuItem5 = new MenuItem();<br />
 mnuItem5.Header = "Add to Queue";</p>
<p>ContextMenu menu = new ContextMenu() { };<br />
 menu.Items.Add(mnuItem1);<br />
 menu.Items.Add(mnuItem2);<br />
 menu.Items.Add(mnuItem3);<br />
 menu.Items.Add(mnuItem4);<br />
 menu.Items.Add(mnuItem5);</p>
<p>(sender as TreeViewItem).ContextMenu = menu;<br />
 }<br />
 else if (type.ToUpper() == "BATCH")<br />
 {<br />
 MenuItem mnuItem1 = new MenuItem();<br />
 mnuItem1.Header = "Show Batch Details";<br />
 MenuItem mnuItem2 = new MenuItem();<br />
 mnuItem2.Header = "Edit Batch";<br />
 MenuItem mnuItem3 = new MenuItem();<br />
 mnuItem3.Header = "Delete Batch";</p>
<p>ContextMenu menu = new ContextMenu() { };<br />
 menu.Items.Add(mnuItem1);<br />
 menu.Items.Add(mnuItem2);<br />
 menu.Items.Add(mnuItem3);</p>
<p>(sender as TreeViewItem).ContextMenu = menu;<br />
 }<br />
 }<br />
 }</p>
<p>private static DependencyObject GetDependencyObjectFromVisualTree(DependencyObject startObject, Type type)<br />
 {<br />
 var parent = startObject;<br />
 while (parent != null)<br />
 {<br />
 if (type.IsInstanceOfType(parent))<br />
 break;<br />
 parent = VisualTreeHelper.GetParent(parent);<br />
 }<br />
 return parent;<br />
 }<br />
 }<br />
}<br />

Bye.

Advertisements

Discover more from Nishant Rana's Weblog

Subscribe to get the latest posts sent to your email.

Posted by Nishant Rana

Categories: WPF

Tags:

4 Responses to “How to – Create dynamic ContextMenu for TreeView in WPF”

  1. Hi, can you upload or send me the project? I trying to load the Packages.xml with his Packages, Package and Batch classes but its not worked. I will appreciate it.

    Thank you!

    Like

    By Anonymous on January 15, 2014 at 1:23 PM

    1. Have you an idea to do the ame thing using MVVM pattern ?

      Like

      By Anonymous on May 12, 2015 at 6:02 PM

  2. “(sender as TreeViewItem).ContextMenu = menu;” can throw a null reference exception. Use “item.ContextMenu=menu;” instead. You should also check to see if item is null and if so, return before attempting to do anything further,

    Like

    By Anonymous on February 11, 2014 at 3:46 PM

  3. This is a good example, except that it doesn’t show how to handle the command binding of a dynamically generated ContextMenu for a TreeViewItem.

    Like

    By dara on August 31, 2017 at 3:12 AM

Leave a Reply



Mobile Site | Full Site


Get a free blog at WordPress.com Theme: WordPress Mobile Edition by Alex King.