Posted by: Zeeshan Amjad | April 17, 2012

ContextMenu in Tree


I came across a question about how to get a treeview item when click on the context menu generated by using data template. In fact it is very straight forward. The only thing we have to remember is that get the parent by using TemplateParent property rather than Parent property. When we call the parent property first time on the context menu then we will get the ContentPresenter (if we populate the TreeView also with data template). And if we call the TemplateParent property again then we will be able to get the TreeViewItem. Here is a simple code to do this.

Code Snippet
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    MenuItem item = sender as MenuItem;

    if (item != null)
    {
        ContentPresenter cp = item.TemplatedParent as ContentPresenter;

        if (cp != null)
        {
            TreeViewItem tvi = cp.TemplatedParent as TreeViewItem;
        }
    }
}

 

At this stage we have TreeView item that generate the context menu and if we get the Header property of this tree view item, then we can get all the data attributes of the object set to this particular item. But remember we have to cast the result get our class.

Here is a complete C# code of our program.

Code Snippet
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;

namespace TreeMenu
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<State> stateList = new ObservableCollection<State>();

        public MainWindow()
        {
            InitializeComponent();

            ObservableCollection<City> citylist1 = new ObservableCollection<City>();
            citylist1.Add(new City() { Name="Baltimore"});
            citylist1.Add(new City() { Name="Frederick"});
            citylist1.Add(new City() { Name="Rockville"});
            State state1 = new State();
            state1.Name = "Maryland";
            state1.Cities = citylist1;

            stateList.Add(state1);

            ObservableCollection<City> citylist2 = new ObservableCollection<City>();
            citylist2.Add(new City() { Name="Los Angeles"});
            citylist2.Add(new City() { Name="Sacramento"});
            citylist2.Add(new City() { Name="San Francisco"});
            citylist2.Add(new City() { Name="San Diego"});
            State state2 = new State();
            state2.Name = "California";
            state2.Cities = citylist2;

            stateList.Add(state2);

            ObservableCollection<City> citylist3 = new ObservableCollection<City>();
            citylist3.Add(new City() { Name="Houston"});
            citylist3.Add(new City() { Name="Dallas"});
            citylist3.Add(new City() { Name="Austin"});
            citylist3.Add(new City() { Name="San Antonio"});
            State state3 = new State();
            state3.Name = "Taxes";
            state3.Cities = citylist3;

            stateList.Add(state3);

            DataContext = stateList;
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            MenuItem item = sender as MenuItem;

            if (item != null)
            {
                ContentPresenter cp = item.TemplatedParent as ContentPresenter;

                if (cp != null)
                {
                    TreeViewItem tvi = cp.TemplatedParent as TreeViewItem;
                }
            }
        }

        private void AnotherMenuItem_Click(object sender, RoutedEventArgs e)
        {
            MenuItem item = sender as MenuItem;

            if (item != null)
            {
                ContentPresenter cp = item.TemplatedParent as ContentPresenter;

                if (cp != null)
                {
                    TreeViewItem tvi = cp.TemplatedParent as TreeViewItem;
                }
            }
        }
    }

    public class City
    {
        public String Name

        { get; set; }
    }

    public class State
    {
        public State()
        {
            this.Cities = new ObservableCollection<City>();
        }

        public String Name
        { get; set; }

        public ObservableCollection<City> Cities
        { get; set; }
    }
}

 

And here is complete XAML for our program.

Code Snippet
<Window x:Class="TreeMenu.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title="Context Menu in Tree" Height="300" Width="400">
    <Grid>
        <TreeView Margin="5" ItemsSource="{Binding}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Path=Cities}">
                    <TextBlock Margin="1" Foreground="Red" Text="{Binding Name}"/>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Margin="1" Foreground="Blue" Text="{Binding Name}">
                                <TextBlock.ContextMenu>
                                    <ContextMenu>
                                        <MenuItem Header="{Binding Name}" FontWeight="Bold" Click="MenuItem_Click"/>
                                        <Separator/>
                                        <MenuItem Header="Another Menu Item" Click="AnotherMenuItem_Click"/>
                                    </ContextMenu>
                                </TextBlock.ContextMenu>
                            </TextBlock>
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>

 

Here is the screen shot of the program.

TreeContextMenu

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: