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
<?xml version="1.0" encoding="utf-8" ?> <Packages> <Package Name="Package 1" Type="Package"> <Batch Name="Batch 1" Type="Batch"/> <Batch Name="Batch 2" Type="Batch"/> </Package> <Package Name="Package 2" Type="Package"> <Batch Name="Batch 1" Type="Batch"/> <Batch Name="Batch 2" Type="Batch"/> </Package> </Packages>
XAML
<Window x:Class="SampleSyncServerAdminTool.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <!--Binding TreeView--> <XmlDataProvider x:Key="MyList" Source="Packages.xml" XPath="Packages"/> <HierarchicalDataTemplate DataType="Packages" ItemsSource="{Binding XPath=*}"> <TextBlock Text="Packages"></TextBlock> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="Package" ItemsSource="{Binding XPath=*}"> <TextBlock Text="{Binding XPath=@Name}"></TextBlock> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="Batch" ItemsSource="{Binding XPath=*}"> <TextBlock Text="{Binding XPath=@Name}"></TextBlock> </HierarchicalDataTemplate> <!-- Resources for Right Hand Side detail grid--> <DataTemplate x:Key="ClosableTabItemTemplate"> <DockPanel Width="120"> <Button Command="{Binding Path=CloseCommand}" Content="X" Cursor="Hand" DockPanel.Dock="Right" Focusable="False" FontFamily="Courier" FontSize="9" FontWeight="Bold" Margin="0,1,0,0" Padding="0" VerticalContentAlignment="Bottom" Width="16" Height="16" /> <ContentPresenter Content="{Binding Path=DisplayName}" VerticalAlignment="Center" /> </DockPanel> </DataTemplate> <DataTemplate x:Key="WorkspacesTemplate"> <TabControl IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}" ItemTemplate="{StaticResource ClosableTabItemTemplate}" Margin="4" /> </DataTemplate> </Window.Resources> <Grid> <DockPanel> <TreeView DockPanel.Dock="Left" Width="150" Name="treeViewPackages" ItemsSource="{Binding Source={StaticResource MyList}}"> <TreeView.Resources> <ContextMenu x:Key="TestMenu"> </ContextMenu> </TreeView.Resources> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="True"/> <EventSetter Event="PreviewMouseRightButtonDown" Handler="OnPreviewMouseRightButtonDown" /> </Style> </TreeView.ItemContainerStyle> </TreeView> <Grid DockPanel.Dock="Right"> <HeaderedContentControl Content="{Binding Path=Workspaces}" ContentTemplate="{StaticResource WorkspacesTemplate}" Header="Workspaces" /> </Grid> </DockPanel> </Grid> </Window>
XAML.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Xml; namespace SampleSyncServerAdminTool { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { DependencyObject obj = e.OriginalSource as DependencyObject; TreeViewItem item = GetDependencyObjectFromVisualTree(obj, typeof(TreeViewItem)) as TreeViewItem; XmlElement selectedElement = (XmlElement)item.Header; string header = selectedElement.Name; if (header.ToUpper() == "PACKAGES") { // Packages root node MenuItem mnuItem = new MenuItem(); mnuItem.Header = "New Package"; ContextMenu menu = new ContextMenu() { }; menu.Items.Add(mnuItem); (sender as TreeViewItem).ContextMenu = menu; } else { string attName = selectedElement.Attributes["Name"].Value; string type = selectedElement.Attributes["Type"].Value; string fullNodeInfo = "Header: " + header + " Attribute Name: " + attName + " Type: " + type; if (type.ToUpper() == "PACKAGE") { MenuItem mnuItem1 = new MenuItem(); mnuItem1.Header = "New Package"; MenuItem mnuItem2 = new MenuItem(); mnuItem2.Header = "Show Package Details"; MenuItem mnuItem3 = new MenuItem(); mnuItem3.Header = "Edit Package"; MenuItem mnuItem4 = new MenuItem(); mnuItem4.Header = "Delete Package"; MenuItem mnuItem5 = new MenuItem(); mnuItem5.Header = "Add to Queue"; ContextMenu menu = new ContextMenu() { }; menu.Items.Add(mnuItem1); menu.Items.Add(mnuItem2); menu.Items.Add(mnuItem3); menu.Items.Add(mnuItem4); menu.Items.Add(mnuItem5); (sender as TreeViewItem).ContextMenu = menu; } else if (type.ToUpper() == "BATCH") { MenuItem mnuItem1 = new MenuItem(); mnuItem1.Header = "Show Batch Details"; MenuItem mnuItem2 = new MenuItem(); mnuItem2.Header = "Edit Batch"; MenuItem mnuItem3 = new MenuItem(); mnuItem3.Header = "Delete Batch"; ContextMenu menu = new ContextMenu() { }; menu.Items.Add(mnuItem1); menu.Items.Add(mnuItem2); menu.Items.Add(mnuItem3); (sender as TreeViewItem).ContextMenu = menu; } } } private static DependencyObject GetDependencyObjectFromVisualTree(DependencyObject startObject, Type type) { var parent = startObject; while (parent != null) { if (type.IsInstanceOfType(parent)) break; parent = VisualTreeHelper.GetParent(parent); } return parent; } } }
Bye.
Filed under: WPF Tagged: WPF
