Container Binding and Checkboxes in RadTreeView

7 posts, 1 answers
  1. Sancho
    Sancho avatar
    3 posts
    Member since:
    Oct 2011

    Posted 25 Oct 2011 Link to this post

    Hello,

    I'm new in Telerik, and I have spent a very long time trying to solve a problem concerning the fact of using Container Bindings to manage checkboxes state in a TreeView.

    So, I have a RadTreeView with a checklist items. I want the checkboxes in front of each items to be checked or not, depending on the values of the IsChecked property in my Business Objects.

    I read on the Internet that the best way to do that was using a Container Binding. That's what I'm doing, but it doesn't work.

    My Business Objects are :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.Serialization;

    namespace BusinessObjects.Entities.Security
    {
        [DataContract]
        public class MoIModule
        {
            [DataMember]
            public string Name { get; set; }
            [DataMember]
            public List<MoOperation> OperationsList { get; set; }
            [DataMember]
            public bool IsChecked { get; set; }

            public MoIModule()
            {
                this.IsChecked = true;
            }
        }
    }


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.Serialization;

    namespace BusinessObjects.Entities.Security
    {
        [DataContract]
        public class MoOperation
        {
            [DataMember]
            public int Id { get; set; }
            [DataMember]
            public string OperationId { get; set; }
            [DataMember]
            public string RoleId { get; set; }
            [DataMember]
            public bool IsChecked { get; set; }

            public MoOperation()
            {
                this.IsChecked = true;
            }
        }
    }

    So, they have a boolean IsChecked property, which is set to true by default for testing.

    Then, in the XAML view, I do that :

    <telerik:ContainerBindingCollection x:Name="BindingsCollection">
                <telerik:ContainerBinding PropertyName="CheckState" Binding="{Binding IsChecked, Mode=TwoWay, Converter={StaticResource CheckStateConverter}}" />
            </telerik:ContainerBindingCollection>
            
            <telerik:HierarchicalDataTemplate
                    x:Key="MoOperation"
                    telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
                <TextBlock Text="{Binding OperationId}" />
            </telerik:HierarchicalDataTemplate>
            
            <telerik:HierarchicalDataTemplate
                    x:Key="MoIModule"
                    ItemTemplate="{StaticResource MoOperation}"
                    ItemsSource="{Binding OperationsList}"
                    telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
                <TextBlock Text="{Binding Name}" />
            </telerik:HierarchicalDataTemplate>
        </telerikNavigation:RadWindow.Resources>

    And, in the code behind, I have the following converter :

    public class CheckStateConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                bool result = (bool)value;
                return result ? ToggleState.On : ToggleState.Off;
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                ToggleState state = (ToggleState)value;
                return state == ToggleState.On ? true : false;
            }
        }

    When I test, the items are correctly loaded, but the checkboxes still empty. The converter isn't even called...

    It seems to be quitly the same thing as we can read on the several examples with Container Bindings in TreeView, so I really don't know the origin of the problem.

    Thanks for your help,

    Sancho
  2. Answer
    Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 28 Oct 2011 Link to this post

    Hi Sancho,

     It's very important in your scenario to implement INotifyPropertyChanged interface in the BusinessObject's classes ( or ViewModels). This way the UI will be notified when a change in ViewModel is performed. You can also check out the attached project where this is realized.

    public bool Checked
            {
                get
                {
                    return this.check;
                }
                set
                {
                    if (this.check != value)
                    {
                        this.check = value;
                        this.NotifyPropertyChanged("Checked");
                    }
                }
            }
    Regards,
    Petar Mladenov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  3. DevCraft banner
  4. Sancho
    Sancho avatar
    3 posts
    Member since:
    Oct 2011

    Posted 02 Nov 2011 Link to this post

    Thanks for your reply.

    I finally found a way to bypass the problem with the ItemPrepared event, that I handle to set the checked property of my object.

    But it's good to know that I had to implement this interface, it should be useful for me in the future.

    Thank you,

    Sancho
  5. Daniela
    Daniela avatar
    20 posts
    Member since:
    Jul 2011

    Posted 17 Nov 2011 Link to this post

    Hi, 

    in this example, do you might know how to disable the employee textbox when the user clicks it's checkbox?


    thanks in advance
  6. Daniela
    Daniela avatar
    20 posts
    Member since:
    Jul 2011

    Posted 18 Nov 2011 Link to this post

    Hi,
    I will explain better my scenario. I modified this example. I added a list<string> to the department class and modified the xaml like this:   <telerik:HierarchicalDataTemplate x:Key="DepartmentTemplate" 
    telerik:ContainerBinding.ContainerBindings="{StaticResource TreeViewBindingsCollection}">
    <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Name}" Width="80" />
                            <telerik:RadComboBox   ItemsSource="{Binding ModelComboBoxItems}"  SelectedIndex="0"  Margin="5,0,0,0"  Width="110" SelectionChanged="RadComboBox_SelectionChanged"/>
    </StackPanel>
    </telerik:HierarchicalDataTemplate>


    I would like to disable only the radcombobox when the user checks the element.
    when I acces the selectedvalue in the RadComboBox_SelectionChanged I only get the   Department:ViewModelBase objet.
    I would like to acces the combobox.

    thanks in advace.
  7. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 22 Nov 2011 Link to this post

    Hi Daniela,

    In order to disable the RadComboBox control in the RadTreeViewItem DataTemplate, you can bind the RadComboBox.IsEnabled property to the Checked property. I modified the solution attached in this thread to demonstrate this approach.

    However, there isn't a straight-forward way of getting the RadComboBoxItem in a datatbound RadComboBox. A possible approach can be to use the ItemContainerGenerator of the control once it is generated:
    private void RadComboBox_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
    {
        RadComboBox comboBox = sender as RadComboBox;
     
        string SelectedItem = e.AddedItems[0] as string;
     
        comboBox.ItemContainerGenerator.StatusChanged += (obg, args) =>
        {
            if ((sender as RadComboBox).ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
            {
                RadComboBoxItem item = comboBox.ItemContainerGenerator.ContainerFromItem(SelectedItem) as RadComboBoxItem;
     
            }
        };
                     
    }
    But I am not sure if this approach will work for you. Can you give us more details about what you need to implement as a logic when the selection of the RadComboBox is changed?

    All the best,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  8. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 22 Nov 2011 Link to this post

    Hi Daniela,

    In order to disable the RadComboBox control in the RadTreeViewItem DataTemplate, you can bind the RadComboBox.IsEnabled property to the Checked property. I modified the solution attached in this thread to demonstrate this approach.

    However, there isn't a straight-forward way of getting the RadComboBoxItem in a datatbound RadComboBox. A possible approach can be to use the ItemContainerGenerator of the control once it is generated:
    private void RadComboBox_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
    {
        RadComboBox comboBox = sender as RadComboBox;
     
        string SelectedItem = e.AddedItems[0] as string;
     
        comboBox.ItemContainerGenerator.StatusChanged += (obg, args) =>
        {
            if ((sender as RadComboBox).ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
            {
                RadComboBoxItem item = comboBox.ItemContainerGenerator.ContainerFromItem(SelectedItem) as RadComboBoxItem;
     
            }
        };
                     
    }
    But I am not sure if this approach will work for you. Can you give us more details about what you need to implement as a logic when the selection of the RadComboBox is changed?

    All the best,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Back to Top
DevCraft banner