Context menu in WPF TreeView (SfTreeView)

29 Jul 20217 minutes to read

This section explains how to show ContextMenu and using built-in commands in the TreeView.

ContextMenu for Nodes

The TreeView provides an entirely customizable context menu to expose the functionality on user interface. You can create context menu for nodes in an efficient manner.

You can set context menu for the nodes by using SfTreeView.ItemContextMenu property.

Built-in Commands

The TreeView provides support for the following built-in commands

<syncfusion:SfTreeView x:Name="sfTreeView"
				ItemsSource="{Binding Folders}"
				ChildPropertyName="SubFiles"
                AllowEditing="True"
                SelectionMode="Multiple">
    <syncfusion:SfTreeView.ItemContextMenu>
        <ContextMenu>
            <MenuItem Command="{x:Static syncfusion:TreeViewCommands.Edit}" CommandParameter="{Binding }"></MenuItem>
            <MenuItem Command="{x:Static syncfusion:TreeViewCommands.DeleteNode}" CommandParameter="{Binding }" ></MenuItem>
            <MenuItem Command="{x:Static syncfusion:TreeViewCommands.DeleteSelectedNodes}" CommandParameter="{Binding }" ></MenuItem>
        </ContextMenu>
    </syncfusion:SfTreeView.ItemContextMenu>
</syncfusion:SfTreeView>

WPF TreeView with ContextMenu using Built-in Commands

Custom Commands

The TreeView allows to show ContextMenu using custom commands when built-in commands does not meet your requirement.

For an example, custom command is used to expand the nodes using context menu in the following example

<syncfusion:SfTreeView x:Name="sfTreeView"
				ItemsSource="{Binding Folders}"
				ChildPropertyName="SubFiles"
                AllowEditing="True"
                SelectionMode="Multiple">
    <syncfusion:SfTreeView.ItemContextMenu>
        <ContextMenu>
            <MenuItem Command="{Binding Path=TreeView.DataContext.ExpandCommand}" CommandParameter="{Binding }"  Header="Expand"/>
        </ContextMenu>
    </syncfusion:SfTreeView.ItemContextMenu>
</syncfusion:SfTreeView>
public class BaseCommand : ICommand
{

    #region Fields
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;
    #endregion

    #region Constructors
    /// <summary>
    /// Creates a new command that can always execute.
    /// </summary>
    /// <param name="execute">The execution logic.</param>

    public BaseCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>

    public BaseCommand(Action<object> execute, Predicate<object> canExecute)
    {

        if (execute == null)
        throw new ArgumentNullException("execute");
        _execute = execute;
        _canExecute = canExecute;
    }
    #endregion
    
    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }
    
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }
    
    #endregion
}

public class FileManagerViewModel
{
    public FileManagerViewModel()
    {
        ExpandCommand = new BaseCommand(ExecuteExpandCommand, CanExecuteExpandCommand);
    }
    
    public BaseCommand ExpandCommand { get; set; }
    
    private bool CanExecuteExpandCommand(object obj)
    {
            if (obj == null)
                return false;
            var treeViewContextMenuInfo = obj as TreeViewItemContextMenuInfo;
            if(treeViewContextMenuInfo.Node.HasChildNodes)
                return true;
            return false;
        }

    private static void ExecuteExpandCommand(object obj)
    {
            if (obj == null)
                return;
            var treeViewContextMenuInfo = obj as TreeViewItemContextMenuInfo;
            treeViewContextMenuInfo.TreeView.ExpandNode(treeViewContextMenuInfo.Node);
    }
}

WPF TreeView with ContextMenu Using Custom Commands

Events

ItemContextMenuOpening Event

ItemContextMenuOpening event occurs while opening the context menu in the TreeView.

ItemContextMenuOpeningEventArgs has the following members which provides the information about ItemContextMenuOpening event

You can cancel showing of ItemContextMenu for certain nodes using custom logic within this event by setting ItemContextMenuOpeningEventArgs.Cancel as true.

sfTreeView.ItemContextMenuOpening += TreeView_ItemContextMenuOpening;

private void TreeView_ItemContextMenuOpening(object sender, Syncfusion.UI.Xaml.TreeView.ItemContextMenuOpeningEventArgs e)
{
    if (e.MenuInfo.Node.Level == 2)
        e.Cancel = true;
}

NOTE

You can refer to our WPF TreeView feature tour page for its groundbreaking feature representations. You can also explore our WPF TreeView example to knows how to represents hierarchical data in a tree-like structure with expand and collapse node options.