Blazor | ComponentOne
Controls / TreeView / Behavior
In This Topic
    Behavior
    In This Topic

    The TreeView control allows you to customize its selection and expanding/collapsing node behavior. It provides several properties that help you customize its behavior. Let us explore how to customize TreeView behavior using different properties in the following sections.

    Node Selection

    By default, TreeView allows you to select a single node at a time. However, you can choose to select a multiple nodes using SelectionMode property of the C1TreeView class. The SelectionMode property manages how the nodes are selected in the TreeView control and accepts values from the C1SelectionMode enumeration. The C1SelectionMode enumeration specifies the selection behavior of the TreeView control by letting you choose one of the following options:

    The following image displays multiple nodes selected in the TreeView.

    Selection of multiple nodes in Treeview

    The following code demonstrates how to set the SelectionMode property to Extended.

    Selection.razor
    Copy Code
    @using C1.Blazor.TreeView
            
    <C1TreeView SelectionMode="C1SelectionMode.Extended">
            <TreeViewItem Header="Devices">
                <TreeViewItem Header="Mobiles">
                    <TreeViewItem Header="Apple" />
                    <TreeViewItem Header="Xiaomi" />
                    <TreeViewItem Header="Nokia" />
                </TreeViewItem>
                <TreeViewItem Header="Tablets" />
                <TreeViewItem Header="Monitor" />
            </TreeViewItem>        
    </C1TreeView>
    

    Back to Top

    Expand/Collapse Nodes

    TreeView allows you to expand/collapse nodes either by clicking the expand/collapse icon or by clicking the node header. By default, the nodes can be expanded or collapsed by clicking the expand/collapse icons. Hence, clicking the node header only selects the node if it is not selected. However, you can change this behavior of the TreeView nodes by setting ExpandOnClick property of the C1TreeView class to true. The ExpandOnClick property determines whether to expand/collapse nodes when user clicks the node header. Hence, setting the ExpandOnClick property to true allows user to expand/collapse nodes by clicking the node header.

    Furthermore, TreeView allows you to expand multiple TreeView nodes simultaneously, by default. This behavior can be managed by using ExpandMode property of the C1TreeView class. The ExpandMode property determines whether a user can expand single or multiple TreeView nodes simultaneously using the TreeViewExpandMode enumeration.

     The following GIF shows how the TreeView behaves when a single TreeView node is allowed to expand at a time.

    Expand one node at a time in Treeview

    The following code snippet demonstrates how to expand a single TreeView node at a time using the ExpandMode property. 

    ExpandNode.razor
    Copy Code
    @using C1.Blazor.TreeView
    @using System.Collections.ObjectModel
    
    <C1TreeView Class="shadow" ItemsSource="@_dataSource" ExpandMode="TreeViewExpandMode.Single" ChildItemsPaths="Subdirectories" DisplayMemberPaths="Name" />
    
    @code {
        readonly ObservableCollection<CompanyRecord> _dataSource = new ObservableCollection<CompanyRecord>()
    {
            new CompanyRecord()
            {
                Name = "Reports",
                Subdirectories = new ObservableCollection<CompanyRecord>
        {
                    new CompanyRecord
                    {
                        Name = "Sales Report",
                        Subdirectories = new ObservableCollection<CompanyRecord>
                {
                            new CompanyRecord {Name = "April Sales"},
                            new CompanyRecord {Name = "May Sales"},
                            new CompanyRecord {Name = "June sales"}
                        }
    
                    },
                    new CompanyRecord
            {
                Name = "Quarter Summary",
            }
                }
            },
            new CompanyRecord
            {
                Name = "Sales Employees",
                Subdirectories = new ObservableCollection<CompanyRecord>
                 {
                            new CompanyRecord {Name = "Bob Tony"},
                            new CompanyRecord {Name = "Sue Winchell"},
                            new CompanyRecord {Name = "Lui Sang"}
                        }
            }
        };
    
        public class CompanyRecord
        {
            public string Name { get; set; }
            public ObservableCollection<CompanyRecord> Subdirectories { get; set; }
        }
    }
    

    Back to Top

    Drag and Drop

    TreeView allows you to drag and drop nodes within the tree and between trees. Let us discuss both the ways in detail in the following setions.

    Drag and drop within a tree

    Setting AllowDragDrop property of the C1TreeView class to true allows users to drag nodes to new positions within the TreeView.

    When dragging is allowed in TreeView, you can drag any node to any position within the tree. Here, nodes can be dragged to a position above, below, or into (as a child of) other nodes. However, you can customize this behavior by handling the following TreeView drag/drop events:

    Drag and drop within Blazor TreeView

    The following code displays how you can set the AllowDragDrop property to allow the drag and drop behavior.

    Razor
    Copy Code
    @using C1.Blazor.Core
    @using C1.Blazor.TreeView
    @using System.Collections.ObjectModel
    
    
    <C1TreeView Class="shadow" ShowLines="true" AllowDragDrop="true" IsExpandedPath="Expanded" ItemsSource="@_dataSource" ChildItemsPaths="Subdirectories" DisplayMemberPaths="Name"
                Style="@_c1Style" KeyboardNavigation="true" SelectionMode="C1SelectionMode.Extended" />
    
    @code {
    readonly C1Style _c1Style = new C1Style
        {
            Height = 500,
            Width = 300,
        };
    
    readonly ObservableCollection<CompanyRecord> _dataSource = new ObservableCollection<CompanyRecord>()
    {
            new CompanyRecord()
            {
                Name = "Reports",
                Subdirectories = new ObservableCollection<CompanyRecord>
        {
                    new CompanyRecord
                    {
                        Name = "Sales Report",
                        Subdirectories = new ObservableCollection<CompanyRecord>
                {
                            new CompanyRecord {Name = "April Sales"},
                            new CompanyRecord {Name = "May Sales"},
                            new CompanyRecord {Name = "June sales"}
                        }
    
                    },
                    new CompanyRecord
            {
                Name = "Quarter Summary",
            }
                }
            },
            new CompanyRecord
            {
                Name = "Sales Employees",
                Subdirectories = new ObservableCollection<CompanyRecord>
                 {
                            new CompanyRecord {Name = "Bob Tony"},
                            new CompanyRecord {Name = "Sue Winchell"},
                            new CompanyRecord {Name = "Lui Sang"}
                        }
            }
        };
    
        public class CompanyRecord
        {
            public string Name { get; set; }
            public ObservableCollection<CompanyRecord> Subdirectories { get; set; }
        }
    }
    

    Drag and drop between trees

    To allow dragging and dropping nodes between different TreeView controls, you must handle the OnDragOver event, set the AllowDragDrop property to true and set the cancel parameter to true if the operation is invalid, or to false if it is valid.

    Drag and drop between two Blazor TreeView

    The following code implements drag and drop operation between two trees:

    Razor
    Copy Code
    @using C1.Blazor.Core
    @using C1.Blazor.TreeView
    @using C1.Blazor.Input
    @using System.Collections.ObjectModel
    
    <div style="margin-bottom: 3rem;">
        <div>Allow dragging between trees <C1CheckBox @bind-IsChecked="@dragBetween" /></div>
    </div>
    
    <div>
        <div style="float: left; margin-right: 15px;">
            <C1TreeView Class="shadow" ShowLines="true" AllowDragDrop="true" IsExpandedPath="Expanded" ItemsSource="@_firstTreeDataSource" ChildItemsPaths="Subdirectories" DisplayMemberPaths="Name"
                        Style="@_c1Style" KeyboardNavigation="true" SelectionMode="C1SelectionMode.Extended" OnDragOver="OnDragOverHandler" />
        </div>
        <div>
            <C1TreeView Class="shadow" ShowLines="true" AllowDragDrop="true" IsExpandedPath="Expanded" ItemsSource="@_secondTreeDataSource" ChildItemsPaths="Subdirectories" DisplayMemberPaths="Name"
                        Style="@_c1Style" KeyboardNavigation="true" SelectionMode="C1SelectionMode.Extended" OnDragOver="OnDragOverHandler" />
        </div>
    </div>
    
    
    @code{
        bool? dragBetween = true;
        readonly C1Style _c1Style = new C1Style
        {
            Height = 500,
            Width = 300,
        };
    
        readonly ObservableCollection<Directory> _firstTreeDataSource = new ObservableCollection<Directory>()
    {
            new Directory()
            {
                Name = "FirstTree 1",
                Subdirectories = new ObservableCollection<Directory>
    {
                    new Directory
                    {
                        Name = "FirstTree 1.1",
                        Subdirectories = new ObservableCollection<Directory>
        {
                            new Directory {Name = "FirstTree 1.1.1"},
                            new Directory {Name = "FirstTree 1.1.2"},
                            new Directory {Name = "FirstTree 1.1.3"},
                        }
    
                    }
                }
            },
            new Directory
            {
                Name = "FirstTree 2",
                Subdirectories = new ObservableCollection<Directory>()
    {
                    new Directory {Name = "FirstTree 2.1"},
                    new Directory {Name = "FirstTree 2.2"}
                }
            },
        };
        readonly ObservableCollection<Directory> _secondTreeDataSource = new ObservableCollection<Directory>()
    {
            new Directory()
            {
                Name = "SecondTree 1",
                Subdirectories = new ObservableCollection<Directory>
    {
                    new Directory
                    {
                        Name = "SecondTree 1.1",
                        Subdirectories = new ObservableCollection<Directory>
        {
                            new Directory {Name = "SecondTree 1.1.1"},
                            new Directory {Name = "SecondTree 1.1.2"},
                            new Directory {Name = "SecondTree 1.1.3"},
                        }
    
                    }
                }
            },
            new Directory
            {
                Name = "SecondTree 2",
                Subdirectories = new ObservableCollection<Directory>()
    {
                    new Directory {Name = "SecondTree 2.1"},
                    new Directory {Name = "SecondTree 2.2"}
                }
            },
        };
    
        public class Directory
        {
            public string Name { get; set; }
            public ObservableCollection<Directory> Subdirectories { get; set; } = new();
            public bool Expanded { get; set; } = true;
        }
    
        void OnDragOverHandler(object sender, C1.Blazor.TreeView.EventArgs.TreeViewDragDropEventArgs arg)
        {
    
            if (arg.TargetDragTree != arg.TargetDropTree && dragBetween.Value)
            {
                arg.Cancel = false;
            }
        }
    }
    

    Back to Top