New to Telerik UI for WinForms? Download free 30-day trial

Product Version 2018.3 911
Product RadTreeView for WinForms

ToggleStateConverter

RadTreeView allows binding the check boxes to a custom property from the associated data object by specifying the RadTreeView.CheckedMember property. A common case is when the specified CheckedMember is a property of custom type and it should be converted to ToggleState which is required by the check boxes in the tree view. This article demonstrates how you can modify the way a property is being displayed and edited by using custom TypeConverters. A Type Converter is used to convert values between data types. Here are the four main methods that are usually used when implementing a custom Type Converter.

  • Override the CanConvertFrom method that specifies which type the converter can convert from.

  • Override the ConvertFrom method that implements the conversion.

  • Override the CanConvertTo method that specifies which type the converter can convert to.

  • Override the ConvertTo method that implements the conversion.

Consider the RadTreeView is populated with Item objects having the following properties:

Item class

public class Item : System.ComponentModel.INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    int m_id;
    int m_parentId;
    string m_name;
    string m_isActive;
    public Item(string name, string isActive, int parent_Id, int id)
    {
        this.m_name = name;
        this.m_isActive = isActive;
        this.m_parentId = parent_Id;
        this.m_id = id;
    }
    public int Id
    {
        get
        {
            return m_id;
        }
        set
        {
            if (this.m_id != value)
            {
                this.m_id = value;
                OnPropertyChanged("Id");
            }
        }
    }
    public int ParentId
    {
        get
        {
            return m_parentId;
        }
        set
        {
            if (this.m_parentId != value)
            {
                this.m_parentId = value;
                OnPropertyChanged("ParentId");
            }
        }
    }
    public string Name
    {
        get
        {
            return m_name;
        }
        set
        {
            if (this.m_name != value)
            {
                this.m_name = value;
                OnPropertyChanged("Name");
            }
        }
    }
    public string IsActive
    {
        get
        {
            return m_isActive;
        }
        set
        {
            if (this.m_isActive != value)
            {
                this.m_isActive = value;
                OnPropertyChanged("IsActive");
            }
        }
    }
}

The tree view is populated with data as follows:

Bind RadTreeView

BindingList<Item> items = new BindingList<Item>();
items.Add(new Item(@"C:\", "false", 0, 1));
items.Add(new Item(@"Documents", "false", 1, 2));
items.Add(new Item(@"Program Files (x86)", "false", 1, 3));
items.Add(new Item(@"D:\", "false", 0, 4));
items.Add(new Item(@"Projects", "false", 4, 5));
this.radTreeView1.DisplayMember = "Name";
this.radTreeView1.ChildMember = "Id";
this.radTreeView1.ParentMember = "ParentId";
this.radTreeView1.CheckedMember = "IsActive";
this.radTreeView1.DataSource = items;
this.radTreeView1.CheckBoxes = true;

The specified CheckedMember is the Item.IsActive property which is typeof(string) indicating the "true" / "false" values. In order to convert these string values to a valid ToggleState you need to use a custom Type Converter. The following code snippet illustrates a sample implementation:

Custom TypeConverter's implementation

public class CustomTypeConverter : TypeConverter
{
    public CustomTypeConverter()
    {
    }
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(ToggleState))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(ToggleState))
        {
            return true;
        }
        return base.CanConvertTo(context, destinationType);
    }
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is ToggleState)
        {
            ToggleState state = (ToggleState)value;
            if (state == ToggleState.On)
            {
                return "true";
            }
            else
            {
                return "false";
            }
        }
        return base.ConvertFrom(context, culture, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        string v = Convert.ToString(value);
        if (v.ToLower() == "true" || v.ToLower() == "yes" || v.ToLower() == "on")
        {
            return ToggleState.On;
        }
        else if (v.ToLower() == "false" || v.ToLower() == "no" || v.ToLower() == "off")
        {
            return ToggleState.Off;
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

Now, you need to apply the custom TypeConverter to the RadTreeView.ToggleStateConverter property:

The property was introduced in R3 2018 (version 2018.3.911).

Set the ToggleStateConverter

this.radTreeView1.ToggleStateConverter = new CustomTypeConverter();

Now, you can toggle/untoggle the nodes and this will be properly reflected to the underlying data object:

WinForms RadTreeView ToggleStateConverter

Note that following this approach it is possible to convert any custom type to ToggleState and thus bind the check boxes in the tree view to any custom property that you have. It is just necessary to implement the specific conversion.

In this article