Edit this page

Command Support

The purpose of this article is to introduce you the command support of the RadTreeViewItems.

Overview

The RadTreeViewItem exposes a Command property of type ICommand. You can use this property to trigger custom logic defined in your business object. Furthermore, you can set the CommandExecutionTrigger property. This property is an enumeration which controls whether the command should be executed after a Click or a DoubleClick on the corresponding RadTreeViewItem.

Demonstration

In this section we will demonstrate how you can trigger custom logic implemented in your business object using the Command Support of the RadTreeViewItem. Hence we will need to create a custom class implementing the INotifyPropertyChanged interface and exposing the following properties:

  • Header of type string
  • Children of type ObservableCollection
  • EditCommand of type DelegateCommand
  • IsInEditMode of type bool

The ViewModelBase class implements the INotifyPropertyChanged interface.

C#

public class ItemModel : ViewModelBase
{
    private bool inInEditMode;
    public bool IsInEditMode
    {
        get
        {
            return this.inInEditMode;
        }
        set
        {
            if (this.inInEditMode != value)
            {
                this.inInEditMode = value;
                this.OnPropertyChanged("IsInEditMode");
            }
        }
    }

    private string header;
    public string Header
    {
        get
        {
            return this.header;
        }
        set
        {
            if (this.header != value)
            {
                this.header = value;
                this.OnPropertyChanged("Header");
            }
        }
    }

    public DelegateCommand EditCommand { get; set; }

    public ObservableCollection<ItemModel> Children { get; set; }
}

VB.NET

Public Class ItemModel
    Inherits ViewModelBase
    Private inInEditMode As Boolean
    Public Property IsInEditMode() As Boolean
        Get
            Return Me.inInEditMode
        End Get
        Set(value As Boolean)
            If Me.inInEditMode <> value Then
                Me.inInEditMode = value
                Me.OnPropertyChanged("IsInEditMode")
            End If
        End Set
    End Property

    Private m_header As String
    Public Property Header() As String
        Get
            Return Me.m_header
        End Get
        Set(value As String)
            If Me.m_header <> value Then
                Me.m_header = value
                Me.OnPropertyChanged("Header")
            End If
        End Set
    End Property

    Public Property EditCommand() As DelegateCommand
        Get
            Return m_EditCommand
        End Get
        Set(value As DelegateCommand)
            m_EditCommand = Value
        End Set
    End Property
    Private m_EditCommand As DelegateCommand

    Public Property Children() As ObservableCollection(Of ItemModel)
        Get
            Return m_Children
        End Get
        Set(value As ObservableCollection(Of ItemModel))
            m_Children = Value
        End Set
    End Property
    Private m_Children As ObservableCollection(Of ItemModel)
End Class

Furthermore, we can create a ViewModel class which will fill and expose an Items collection of type ObservableCollection. Also, this class will hold the custom logic which will be triggered by the command of the RadTreeViewItem

C#

public class ViewModel
{
    public ViewModel()
    {
        this.Items = new ObservableCollection<ItemModel>();
        this.GenerateItems();
    }

    public ObservableCollection<ItemModel> Items { get; set; }

    private void GenerateItems()
    {
        ObservableCollection<ItemModel> children;
        for (byte j = 1; j < 5; j++)
        {
            children = new ObservableCollection<ItemModel>();
            for (byte i = 1; i < 4; i++)
            {
                children.Add(new ItemModel()
                {
                    Header = string.Format("Child {0} of root {1}", i, j),
                    EditCommand = new DelegateCommand((x) => this.OnEditCommandExecute(x))
                });
            }
            this.Items.Add(new ItemModel()
            {
                Header = string.Format("Root Item {0}", j),
                Children = children,
                EditCommand = new DelegateCommand((x) => this.OnEditCommandExecute(x))
            });
        }
    }

    private void OnEditCommandExecute(object sender)
    {
        var item = sender as ItemModel;
        if (item != null)
        {
            item.IsInEditMode = true;
        }
    }
}

VB.NET

Public Class ViewModel
    Public Sub New()
        Me.Items = New ObservableCollection(Of ItemModel)()
        Me.GenerateItems()
    End Sub

    Public Property Items() As ObservableCollection(Of ItemModel)
        Get
            Return m_Items
        End Get
        Set(value As ObservableCollection(Of ItemModel))
            m_Items = Value
        End Set
    End Property
    Private m_Items As ObservableCollection(Of ItemModel)

    Private Sub GenerateItems()
        Dim children As ObservableCollection(Of ItemModel)
        For j As Byte = 1 To 4
            children = New ObservableCollection(Of ItemModel)()
            For i As Byte = 1 To 3
                children.Add(New ItemModel() With {
                    .Header = String.Format("Child {0} of root {1}", i, j),
                    .EditCommand = New DelegateCommand(Function(x) Me.OnEditCommandExecute(x))
                })
            Next
            Me.Items.Add(New ItemModel() With {
                .Header = String.Format("Root Item {0}", j),
                .Children = children,
                .EditCommand = New DelegateCommand(Function(x) Me.OnEditCommandExecute(x))
            })
        Next
    End Sub

    Private Sub OnEditCommandExecute(sender As Object)
        Dim item = TryCast(sender, ItemModel)
        If item IsNot Nothing Then
            item.IsInEditMode = True
        End If
    End Sub
End Class

In MVVM scenarios it is best to use a Style to set the Command and CommandExecutionTrigger properties of the RadTreeViewItems. For this purpose we will also allow the editing of items and we will use the boolean IsInEditMode property defined in the custom ItemModel class to set the corresponding RadTreeViewItem in edit mode. This will be done in the OnEditCommandExecute() method implemented in the ViewModel class. In order to differ the item that invokes the command we can pass each RadTreeViewItem's DataContext as CommandParameter to the method where custom logic will be implemented. In order to achieve this we can use the RelativeSource binding.

XAML

<Grid>
    <Grid.Resources>
        <HierarchicalDataTemplate x:Key="HDT" ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Header, Mode=TwoWay}" />
        </HierarchicalDataTemplate>
        <Style TargetType="telerik:RadTreeViewItem">
            <Setter Property="Command" Value="{Binding EditCommand}" />
            <Setter Property="CommandParameter" Value="{Binding}" />
            <Setter Property="CommandExecutionTrigger" Value="DoubleClick" />
            <Setter Property="IsInEditMode" Value="{Binding IsInEditMode, Mode=TwoWay}" />
        </Style>
    </Grid.Resources>
    <telerik:RadTreeView IsEditable="True"
                     IsExpandOnDblClickEnabled="False"
                     ItemTemplate="{StaticResource HDT}"
                     ItemsSource="{Binding Items}" />
</Grid>