How to determine which item was checked?

7 posts, 0 answers
  1. Jeramy
    Jeramy avatar
    12 posts
    Member since:
    Sep 2015

    Posted 04 Dec 2015 Link to this post

    I am using the checkboxes in a RadTreeView. The treeview items are bound to my own heirarchical type called TreeNode. When an item is checked how do I determine which TreeNode object was checked?

    Currently I am using a command to handle the IsChecked event of the control. I am passing the event arguments to the command. I can get access to all the checked items in the tree as TreeNodes, but am at a loss as to which one was actually last checked.

     <telerik:RadTreeView x:Name="TreePermissions"
                                                     DockPanel.Dock="Top"
                                                     MinHeight="50"
                                                     BorderBrush="Black"
                                                     BorderThickness="1"
                                                     Margin="5,0,5,0"
                                                     IsOptionElementsEnabled="True"
                                                     ItemsSource="{Binding UserPermissions}"
                                                     ItemPrepared="TreePermissions_ItemPrepared">
                                    
                                    <telerik:EventToCommandBehavior.EventBindings>
                                        <telerik:EventBinding Command="{Binding PermissionCheckedCommand}" EventName="Checked"
                                                              PassEventArgsToCommand="True" />
                                    </telerik:EventToCommandBehavior.EventBindings>
                                    
                                    <telerik:RadTreeView.ItemContainerStyle>
                                        <Style TargetType="{x:Type telerik:RadTreeViewItem}">
                                            <Setter Property="IsExpanded" Value="True"/>
                                            <Setter Property="IsChecked" Value="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}"/>
                                            <Setter Property="IsEnabled" Value="{Binding IsEnabled, UpdateSourceTrigger=PropertyChanged}"/>
                                        </Style>
                                    </telerik:RadTreeView.ItemContainerStyle>
                                </telerik:RadTreeView>

     

    private void OnPermissionChecked(object obj)
            {
                var args = obj as Telerik.Windows.Controls.RadTreeViewCheckEventArgs;
                Telerik.Windows.Controls.RadTreeViewItem item = args.OriginalSource as Telerik.Windows.Controls.RadTreeViewItem;
                // TreeNode node = item as TreeNode; // This does not work, cannot cast/convert for some reason
                Telerik.Windows.Controls.RadTreeView source = args.Source as Telerik.Windows.Controls.RadTreeView;
                if (source != null)
                {
                    List<TreeNode> temp = source.CheckedItems.Cast<TreeNode>().ToList();
                }
            }

  2. Ivan
    Admin
    Ivan avatar
    44 posts

    Posted 08 Dec 2015 Link to this post

    Hello Jeramy,

    We recommend to avoid using the RadTreeView's built-in checkbox functionality in a data binding scenario. Instead you can take a look at the  Implement a Tri-State CheckBox logic using MVVM help article. At the end of the article there is a link to the whole sample project, explained in it.

    Please try this and let me know if it works for you.

    Regards,
    Ivan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
  4. Jeramy
    Jeramy avatar
    12 posts
    Member since:
    Sep 2015

    Posted 09 Dec 2015 in reply to Ivan Link to this post

    1) What do you recommend avoiding the built-in check boxes? Why do they exist in a WPF control if you recommend avoiding them for data-binding?

    2) In the example you provided, how do I determine which specific tree node was checked? I have two model classes that need to be maintained in congruence with the TreeNode class that was developed specifically to bind to the RadTreeView. So I need to intercept which node was checked and then apply changes to these other model classes. What do you recommend?

     Thanks!!!

  5. Ivan
    Admin
    Ivan avatar
    44 posts

    Posted 10 Dec 2015 Link to this post

    Hi Jeramy,

    1) What do you recommend avoiding the built-in check boxes? Why do they exist in a WPF control if you recommend avoiding them for data-binding?

    The buit-in checkboxes of the TreeView are recommended to be used with small trees without virtualization or data binding. If there is virtualization (or data binding) they are highly not recommended.
    In such scenarios we recommend using ItemTemplate with a CheckBox inside, as shown in the article I've sent you in my last reply. This is demonstrated also in the attached project. 

    2)  In the example you provided, how do I determine which specific tree node was checked?

    There is a simple example in the attached project demonstrating how to capture the checked item. Basically, you can get and save it in the setter of the IsChecked property of the treeitem's view model.

    Regards,
    Ivan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Heiko
    Heiko avatar
    124 posts
    Member since:
    Oct 2012

    Posted 02 Dec Link to this post

    I had a similar problem and found a nice solution to it. It is easier than what Telerik did in their example which I find too complicated. It's not the pure MVVM way but I think also a viable option.

    My object is named "MailRecipient" and it has a IsSelected property as well as Name and EMail. First, I use a grouped QueryableCollectionView for my ItemsSource.

    this.RecipientView = new QueryableCollectionView(this.NameList);
    this.RecipientView.GroupDescriptors.Add(new GroupDescriptor()
        { Member = "Group", SortDirection = ListSortDirection.Ascending });

     

    The RadTreeView is bound to the RecipientView's Group property and has a simple HierarchicalDataTemplate.

    <DataTemplate x:Key="MailRecipientDataTemplate"  DataType="{x:Type localModels:MailRecipient}">
        <StackPanel Orientation="Horizontal">
             <TextBlock Text="{Binding Name}" />
             <TextBlock Text="{Binding EMail}" Margin="10 0 0 0" />
         </StackPanel>
     </DataTemplate>
    <HierarchicalDataTemplate x:Key="MailTreeViewDataTemplate"
        ItemsSource="{Binding Items}"
        ItemTemplate="{StaticResource MailRecipientDataTemplate}">
        <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
             <TextBlock Text="{Binding Path=Name}" />
             <TextBlock Text="{Binding Path=ItemCount, StringFormat={} ({0} recipients)}" />
         </StackPanel>
    </HierarchicalDataTemplate>

     

    <telerik:RadTreeView ItemsSource="{Binding RecipientView.Groups}"
                         IsOptionElementsEnabled="True"
                         IsTriStateMode="True"
                         Checked="RadTreeView_Checked"
                         Unchecked="RadTreeView_Unchecked"
                         ItemTemplate="{StaticResource MailTreeViewDataTemplate}">
    </telerik:RadTreeView>

    Then in code behind I react to the Checked/Unchecked event of the RadTreeView. It is possible that these events get called several times when you click just one item: first because the group header element gets checked/unchecked, the other times for each of the child elements. When the RadTreeViewItem.Item property is the type of my MailRecipient class I set the IsSelected property of my object to the CheckState of the RadTreeViewItem which can bei On/Off/Indeterminate.

    private void RadTreeView_Checked(object sender, Telerik.Windows.RadRoutedEventArgs e)
    {
        CheckAndUncheckItem(e.OriginalSource as RadTreeViewItem);
    }
     
    private void RadTreeView_Unchecked(object sender, Telerik.Windows.RadRoutedEventArgs e)
    {
        CheckAndUncheckItem(e.OriginalSource as RadTreeViewItem);
    }
     
    private void CheckAndUncheckItem(RadTreeViewItem treeViewItem)
    {
        if (treeViewItem != null)
        {
            var recipient = treeViewItem.Item as MailRecipient;
            if (recipient != null)
            {
                recipient.IsSelected = treeViewItem.CheckState == ToggleState.On;
            }
        }
    }

     

     

  7. Lance | Tech Support Engineer, Sr.
    Admin
    Lance | Tech Support Engineer, Sr. avatar
    138 posts

    Posted 5 days and 23 hours ago Link to this post

    Hi Heiko,

    Yes, this is a good option for scenarios where you can use code-behind as we pass the TreeViewItem in the event args.

    Thank you for sharing with the community!

    Regards,
    Lance | Tech Support Engineer, Sr.
    Telerik by Progress
    Telerik UI for WPF is ready for Visual Studio 2017 RC! Learn more.
  8. Heiko
    Heiko avatar
    124 posts
    Member since:
    Oct 2012

    Posted 3 days and 7 hours ago in reply to Lance | Tech Support Engineer, Sr. Link to this post

    My solution has one small restriction. The child elements in the second level are checked only when they have been loaded at least once. This means if you click a parent element which has not been expanded before the child elements under this parent are not checked. What I do now is to "ExpandAll()" elements which is fine with just a few of them. I didn't find a method to "LoadAll()" children.

    Regards
    Heiko

Back to Top
UI for WPF is Visual Studio 2017 Ready