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 /> <?xml version="1.0" encoding="utf-8" ?><br /> <Packages><br /> <Package Name="Package 1" Type="Package"><br /> <Batch Name="Batch 1" Type="Batch"/><br /> <Batch Name="Batch 2" Type="Batch"/><br /> </Package><br /> <Package Name="Package 2" Type="Package"><br /> <Batch Name="Batch 1" Type="Batch"/><br /> <Batch Name="Batch 2" Type="Batch"/><br /> </Package><br /> </Packages><br />
XAML
<br />
<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"><br />
<Window.Resources><br />
<!--Binding TreeView--><br />
<XmlDataProvider x:Key="MyList" Source="Packages.xml" XPath="Packages"/></p>
<p><HierarchicalDataTemplate DataType="Packages" ItemsSource="{Binding XPath=*}"><br />
<TextBlock Text="Packages"></TextBlock><br />
</HierarchicalDataTemplate></p>
<p><HierarchicalDataTemplate DataType="Package" ItemsSource="{Binding XPath=*}"><br />
<TextBlock Text="{Binding XPath=@Name}"></TextBlock><br />
</HierarchicalDataTemplate></p>
<p><HierarchicalDataTemplate DataType="Batch" ItemsSource="{Binding XPath=*}"><br />
<TextBlock Text="{Binding XPath=@Name}"></TextBlock><br />
</HierarchicalDataTemplate></p>
<p><!-- Resources for Right Hand Side detail grid--></p>
<p><DataTemplate x:Key="ClosableTabItemTemplate"><br />
<DockPanel Width="120"><br />
<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 />
/><br />
<ContentPresenter<br />
Content="{Binding Path=DisplayName}"<br />
VerticalAlignment="Center"<br />
/><br />
</DockPanel><br />
</DataTemplate></p>
<p><DataTemplate x:Key="WorkspacesTemplate"><br />
<TabControl<br />
IsSynchronizedWithCurrentItem="True"<br />
ItemsSource="{Binding}"<br />
ItemTemplate="{StaticResource ClosableTabItemTemplate}"<br />
Margin="4"<br />
/><br />
</DataTemplate></p>
<p></Window.Resources><br />
<Grid><br />
<DockPanel><br />
<TreeView DockPanel.Dock="Left" Width="150" Name="treeViewPackages"</p>
<p> ItemsSource="{Binding Source={StaticResource MyList}}"><br />
<TreeView.Resources><br />
<ContextMenu x:Key="TestMenu"><br />
</ContextMenu><br />
</TreeView.Resources><br />
<TreeView.ItemContainerStyle><br />
<Style TargetType="{x:Type TreeViewItem}"><br />
<Setter Property="IsExpanded" Value="True"/><br />
<EventSetter Event="PreviewMouseRightButtonDown"<br />
Handler="OnPreviewMouseRightButtonDown" /><br />
</Style> </TreeView.ItemContainerStyle><br />
</TreeView><br />
<Grid DockPanel.Dock="Right"><br />
<HeaderedContentControl<br />
Content="{Binding Path=Workspaces}"<br />
ContentTemplate="{StaticResource WorkspacesTemplate}"<br />
Header="Workspaces"<br />
/><br />
</Grid><br />
</DockPanel><br />
</Grid><br />
</Window><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 />
/// <summary><br />
/// Interaction logic for MainWindow.xaml<br />
/// </summary><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.
Discover more from Nishant Rana's Weblog
Subscribe to get the latest posts sent to your email.

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!
LikeLike
Have you an idea to do the ame thing using MVVM pattern ?
LikeLike
“(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,
LikeLike
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.
LikeLike