Change context menu in WPF TreeView for data

Is there a way to specify in a TreeView's HierarchicalDataTemplate to use a different ContextMenu depending on a property on the data an item is bound to?

For instance, display one ContextMenu if Item.IsFile is true, display a different one if Item.IsFolder is true, etc.


This is example for ListBox, I think you can easily modify it to work with TreeView.



    <ContextMenu x:Key="FileContextMenu">
    <ContextMenu x:Key="DirContextMenu">

    <local:ItemToContextMenuConverter x:Key="ContextMenuConverter" />        


<ListBox x:Name="SomeList">
            <Label Content="{Binding Path=Name}" ContextMenu="{Binding Converter={StaticResource ContextMenuConverter}}"/>


class Item
    public string Name { get; set; }
    public bool IsFile { get; set; }

[ValueConversion(typeof(Item), typeof(ContextMenu))]
public class ItemToContextMenuConverter : IValueConverter
    public static ContextMenu FileContextMenu;
    public static ContextMenu DirContextMenu;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        Item item = value as Item;
        if (item == null) return null;

        return item.IsFile ? FileContextMenu : DirContextMenu;

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        throw new Exception("The method or operation is not implemented.");

private void Window_Loaded(object sender, RoutedEventArgs e)
            = this.Resources["FileContextMenu"] as ContextMenu;
            = this.Resources["DirContextMenu"] as ContextMenu;

        List<Item> items = new List<Item>();
        items.Add(new Item() { Name = "First", IsFile = true });
        items.Add(new Item() { Name = "Second", IsFile = false });

        SomeList.ItemsSource = items;

Hi I am doing similar thing on TreeView and I don't like that ItemToContextMenuConverter is executed on each item even if it is not used. It's maybe ok in a small project but if you add Enable/Disable code for each MenuItem than it can be slow.

This is maybe not the best (I just started with WPF), but I will share it with you.

Menu Resources:

  <ContextMenu x:Key="MnuFolderFavorites" StaysOpen="True">
    <MenuItem Header="Remove from Favorites" Click="MnuFolder_RemoveFromFavorites_Click"></MenuItem>
  <ContextMenu x:Key="MnuFolder" StaysOpen="True">
    <MenuItem Header="New Folder"></MenuItem>
    <MenuItem Header="Rename" x:Name="MnuFolderRename" Click="MnuFolder_Rename_Click"></MenuItem>
    <MenuItem Header="Add to Favorites" Click="MnuFolder_AddToFavorites_Click"></MenuItem>


<TreeView x:Name="TvFolders">
    <HierarchicalDataTemplate DataType="{x:Type data:Folder}" ItemsSource="{Binding Items}">
      <StackPanel Orientation="Horizontal" PreviewMouseRightButtonDown="TvFoldersStackPanel_PreviewMouseRightButtonDown">
        <Image Width="20" Height="20" Source="{Binding ImagePath}" />
        <TextBlock Text="{Binding Title}" Margin="5,0,0,0" />


private void TvFoldersStackPanel_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) {
  ((StackPanel) sender).ContextMenu = null;
  Data.Folder item = (Data.Folder) ((StackPanel) sender).DataContext;
  if (!item.Accessible) return;
  if (item.Parent != null && item.Parent.Title.Equals("Favorites")) {
    ((StackPanel) sender).ContextMenu = MainWindow.Resources["MnuFolderFavorites"] as ContextMenu;
  } else {
    ((StackPanel) sender).ContextMenu = MainWindow.Resources["MnuFolder"] as ContextMenu;
    foreach (MenuItem menuItem in ((StackPanel) sender).ContextMenu.Items) {
      switch (menuItem.Name) {
        case "MnuFolderRename": {
          menuItem.IsEnabled = item.Parent != null;

private void MnuFolder_RemoveFromFavorites_Click(object sender, RoutedEventArgs e) {
  string path = ((Data.Folder)((MenuItem)sender).DataContext).FullPath;

Need Your Help

Customizing Google Custom Search

forms search google-custom-search

Does anyone know how to remove the extra branding on the google custom search?

Change view properties after adding it as subview

ios iphone objective-c uiview

I'm creating app where i'm using pagedFlowView. I have custom view (mainDetailV) with ImageView as background and label on top. I'm using PagedFlowView delegate method to init all the views in it: