Quantcast
Channel: WPF – Nishant Rana's Weblog
Viewing all articles
Browse latest Browse all 6

Creating dynamic ContextMenu for TreeView in WPF

$
0
0

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

Viewing all articles
Browse latest Browse all 6

Trending Articles