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.
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