Search code examples
c#wpftreeviewhierarchicaldatatemplate

get all selected item in treeview


Hello i have a treeview which itemtemplate is checkbox. i want to get the selected items ischecked = true how can i do this?

I want to get all the items selected in a list. Some items may have sub items

 <TreeView x:Name="chkTree" ItemsSource="{Binding TreeRoot}">
                        <TreeView.ItemTemplate>
                            <HierarchicalDataTemplate DataType = "{x:Type local:CheckTreeSource}" ItemsSource = "{Binding Children}">
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox IsChecked="{Binding IsChecked}"/>
                                    <TextBlock Text="{Binding Text}"/>
                                </StackPanel>
                            </HierarchicalDataTemplate>
                        </TreeView.ItemTemplate>
                    </TreeView>

UPDATE:

i tried this but this work only if a item is selected with sub items, But if only sub-item is selected (the item itself is not selected only some of its sub-items) This code does not work

foreach (var item in chkTree.Items)
            {
                if (((CheckTreeSource)item).IsChecked== true && ((CheckTreeSource)item).Children !=null)
                {
                    foreach (var subitem in ((CheckTreeSource)item).Children)
                    {
                        MessageBox.Show(((CheckTreeSource)subitem).Text + "");

                    }

                }
}

Solution

  • You could have a static method that recursively adds checked items to a collection:

    public static void AddCheckedItems(
        CheckTreeSource item, ICollection<CheckTreeSource> checkedItems)
    {
        if (item.IsChecked)
        {
            checkedItems.Add(item);
        }
    
        if (item.Children != null)
        {
            foreach (var childItem in item.Children)
            {
                AddCheckedItems(childItem, checkedItems); // recursive call
            }
        }
    }
    

    Then call it with the root item as start:

    var checkedItems = new List<CheckTreeSource>();
    
    AddCheckedItems(TreeRoot, checkedItems);
    

    Alternatively declare the method in the CheckTreeSource class:

    public void AddCheckedItems(ICollection<CheckTreeSource> checkedItems)
    {
        if (IsChecked)
        {
            checkedItems.Add(this);
        }
    
        if (Children != null)
        {
            foreach (var childItem in Children)
            {
                childItem.AddCheckedItems(checkedItems);
            }
        }
    }
    

    and call it like:

    var checkedItems = new List<CheckTreeSource>();
    
    TreeRoot.AddCheckedItems(checkedItems);
    

    You may also want to take a look at this: https://stackoverflow.com/a/7063002/1136211