This is a migrated thread and some comments may be shown as answers.

How to disable a treeview item in the treeview

4 Answers 293 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Rajesh
Top achievements
Rank 1
Rajesh asked on 04 Apr 2013, 03:35 AM
private ObservableCollection<Bundle> _availableProductBundles;
public ObservableCollection<Bundle> AvailableProductBundles
{
    get
    {
        return _availableProductBundles;
    }
    set
    {
        _availableProductBundles = value;
        RaisePropertyChanged(PropertyNames.AVAILABLE_PRODUCT_BUNDLES);
    }
}
private void LoadAvailableBundle(PortableBundleCatalog pbc)
 {  
     AvailableProductBundles = new ObservableCollection<Bundle>();
     Bundle b;
     Channel c;
     string strBundleName = string.Empty;
     string strChannelName = string.Empty;
 
     foreach (PortableBundle pBundle in pbc.Bundles)
     {
         //strBundleName = pBundle.BundleName;
         strBundleName = pBundle.Product;
         strChannelName = pBundle.Name;
          
 
         if (_availableProductBundles.Count != 0)
         {
             var containsBundleName = AvailableProductBundles.Where(X => X.BName == strBundleName).FirstOrDefault();
 
             if (containsBundleName != null)
             {  
                 c = new Channel(strChannelName);
                 containsBundleName.Channels.Insert(containsBundleName.Channels.Count, c);
             }
             else
             {
                 b = new Bundle(strBundleName);
                 c = new Channel(strChannelName);
                 b.Channels.Add(c);
                 AvailableProductBundles.Add(b);
             }
         }
         else
         {
             b = new Bundle(strBundleName);
             c = new Channel(strChannelName);
             b.Channels.Add(c);                   
             _availableProductBundles.Add(b);
         }
     }       
 
 }
Bundle.cs
 
using System.Collections.ObjectModel;
using Telerik.Windows.Controls;
 
namespace WMCustomizationTool.Model
{
    public class Bundle
    {
        public Bundle(string strBName)
        {
            this.BName = strBName;
            this.Channels = new ObservableCollection<Channel>();
        }
 
        private string _bundleName;
        public string BName
        {
            get
            {
                return _bundleName;
            }
            set
            {
                _bundleName = value;
            }
        }
 
        private ObservableCollection<Channel> _channels;
        public ObservableCollection<Channel> Channels
        {
            get
            {
                return _channels;
            }
            set
            {
                _channels = value;                            
            }
        }
 
        private bool _isEnabled = true;
        public bool isEnabled
        {
            get
            {
                return _isEnabled;
            }
            set
            {
                _isEnabled = value;
            }
 
        }
 
        private bool _isExpanded;
        public bool isExpanded
        {
            get
            {
                return _isExpanded;
            }
 
            set
            {
                _isExpanded = value;
            }
        }       
    }
}
Channel.cs
 
using System;
using Telerik.Windows.Controls;
 
namespace WMCustomizationTool.Model
{
    public class Channel
    {
        public Channel(string strCName)
        {
            this.CName = strCName;
        }
 
        private string _channelName;
        public string CName
        {
            get
            {
                return _channelName;
            }
            set
            {
                _channelName = value;
            }
        }
    }
}
private void EnableOrDisableBundlesForSelectedPackage(PortableBundle portableBundle, bool mode)
 {
 
     foreach (Bundle bb in AvailableProductBundles)
     {
         foreach (Channel cc in bb.Channels)
         {
             if (cc.CName == portableBundle.Name)
             {
                 bb.isEnabled = false;   --------------------------------> doing this is NOT disabling my the treeviewItem
             }
         }
     }
 }
<
UserControl x:Class="WMCustomizationTool.View.PackageEditorAvailableBundlesView"
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    xmlns:view="clr-namespace:WMCustomizationTool.View"
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"            
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
 
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/WMCustomizationTool;component/Resources/WMCustomizationToolTheme.xaml"/>
            </ResourceDictionary.MergedDictionaries>
 
            <Style x:Key="RADTreeViewItemStyle" TargetType="telerik:RadTreeViewItem">               
                <Setter Property="HorizontalAlignment" Value="Left"/>
                <Setter Property="CheckState" Value="Off" />
                <Setter Property="BorderThickness" Value="1" />
                <Setter Property="Padding" Value="1 0 5 0" />
                <Setter Property="IsDropAllowed" Value="True" />
                <Setter Property="ItemsOptionListType" Value="Default" />
                <Setter Property="IsEnabled" Value="True" />
                <Setter Property="MinHeight" Value="24" />
 
                <Setter Property="Template" Value="{StaticResource TreeViewItemDefaultTemplate}" />
                <Setter Property="ItemsPanel">
                    <Setter.Value>
                        <ItemsPanelTemplate>
                            <telerik:TreeViewPanel VerticalAlignment="Bottom" />
                        </ItemsPanelTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
             
            <telerik:ContainerBindingCollection x:Name="BindingsCollections">
                <telerik:ContainerBinding PropertyName="IsEnabled" Binding="{Binding isEnabled, Mode=TwoWay}"/>
                <telerik:ContainerBinding PropertyName="IsExpanded" Binding="{Binding isExpanded, Mode=TwoWay}"/>
            </telerik:ContainerBindingCollection>
 
            <telerik:HierarchicalDataTemplate x:Key="ChannelTemplate" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollections}">
                <TextBlock Text="{Binding CName}" />
            </telerik:HierarchicalDataTemplate>
 
            <telerik:HierarchicalDataTemplate x:Key="BundleTemplate" ItemTemplate="{StaticResource ChannelTemplate}"
                                          ItemsSource="{Binding Channels}" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollections}">
                <TextBlock Text="{Binding BName}" />
            </telerik:HierarchicalDataTemplate>
 
        </ResourceDictionary>
    </UserControl.Resources>
 
    <Grid x:Name="LayoutRoot" >
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
 
            <telerik:RadTreeView x:Name="BundlesLocationsView_RadTreeView" VerticalAlignment="Stretch" ItemContainerStyle="{StaticResource RADTreeViewItemStyle}"
                                 SelectionMode="Single" IsExpandOnSingleClickEnabled="True" ScrollViewer.VerticalScrollBarVisibility="Auto"
                                 ItemTemplate="{StaticResource BundleTemplate}" ItemsSource="{Binding Path=AvailableProductBundles, Mode=TwoWay}">
            </telerik:RadTreeView>
 
        </Grid>
    </Grid>
</UserControl>
Hi there,

  Here is the scenario I have. I have a tree populated with one parent node with multiple child node.
 Say for (e.g) - A, B, C are the parent node.  A1, A2, B1, B2, C1, C2 are its respective children.

There is a combo box populated with value. Each value has ONE or MORE children stated above (A1, A2, B1, B2, C1, C2).

So, when I select a value from the combobox, the treeview that has the respective node (including parent) should be disabled.
Say for(e.g) If the value in the combobox has "A1" then the treeview of "A -A1, A2" should be disabled.

I am doing this using "HierarchicalDataTemplate".

But I could not get the Tree to disable a particular Parent or child item.

Pasting code that I have for XAML and View Model and Model declaration.

Please do help me.

4 Answers, 1 is accepted

Sort by
0
Rajesh
Top achievements
Rank 1
answered on 04 Apr 2013, 03:52 AM
Attached is the screen shot for how it should look like

0
Accepted
Pavel R. Pavlov
Telerik team
answered on 04 Apr 2013, 07:17 PM
Hi Rajesh,

In your scenario it will be best if you bind the ComboBoxItem.IsSelected, RadTreeViewItem.IsEnabled and RadTreeViewItem.IsExpanded properties to properties of your business object. By doing so you will be able to implement all your custom logic in the ViewModel. Please note that when a RadTreeViewItem is disabled, it will automatically disable its children. Hence, if you disable the Root of the selected branch you will achieve your goal. In order to find the Root of a branch, all items should keep a reference to their parent. Then you will be able to trigger custom disable logic when the selection of the ComboBox control is changed (due to the bindings).

Also, looking at your code snippets I noticed that you have defined a Style for the RadTreeViewItems where you explicitly apply the IsEnabled property to True and you also use ContainerBindings to bind the property. But if your application is targeting Silverlight 5, then you can simply use setter bindings to apply the IsExpanded and IsEnabled bindings and remove the ContainerBindingsCollection.

For your convenience we implemented this approach in the attached project. Please take a look at it and let us know if it works for you.

Regards,
Pavel R. Pavlov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Rajesh
Top achievements
Rank 1
answered on 10 Apr 2013, 05:57 PM
Hi Pavel,

  I may be late in reply but all these days was working out with your given solution. Tell you what, the idea was awesome. It worked well.
Great help by providing sample solution.

Thanks a lot!

I would like to have one more solution here. As said before, the tree going to have 1 parent and 1 child. Likewise it is going to be 1000 to 10,000+ nodes. This entire treeview is working in one tab view. There is another tab view for other logic. So, When I switch between the tabs and come back to the "TreeView" tab, I have to refresh the treeview. Which means, I have to add if newly found Parent-child node. Also, "Enable" all "Disabled" nodes. Right now, I do enable the nodes by iterating through all the nodes.

            foreach (ProductBundle pBundle in AvailableProductBundles)
            {
                foreach (Bundle bundle in pBundle.Bundles)
                {
                    bundle.Parent.IsEnabled = true;
                }
            }

I believe iterating through all the 1000 or 10,000 nodes using the foreach() is going to have preformance issue, slowness.. (This is my guess).

Question: - 1. What is the fastest (performance) way to do ? With sample please.

This would be great help.

Thanks a lot again!
0
Pavel R. Pavlov
Telerik team
answered on 11 Apr 2013, 03:52 PM
Hi Rajesh,

I am not sure what you mean by "refreshing the TreeView". If you rest the ItemsSource collection (e.g. reference a new collection) of the RadTreeView control and you have 100,000+ items you are going to have some performance issues.

The better approach could be to update the ItemsSource collection. We believe that Bindings will do the job. Please keep in mind that when the underling collection is updated (item is removed/added/changed) the RadTreeView control will also update, due to the binding and the property changed event. By following this approach the control will have to update only a part of the collection (the updated items), rather than all the items.

Furthermore, you can set, the already bound, IsEnabled property whenever you update an item and the binding will notify the RadTreeView control for the change immediately. The same setting can be done when you create your business collection.

Also, if you are using our RadTabControl you can set its IsContentPreserved property to True to leverage even more the overall performance of your application. By setting it you will keep the content of the RadTabItems in memory and this will help you when you switch between the tabs.

I hope these directions will help you.

Regards,
Pavel R. Pavlov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
TreeView
Asked by
Rajesh
Top achievements
Rank 1
Answers by
Rajesh
Top achievements
Rank 1
Pavel R. Pavlov
Telerik team
Share this question
or