1
votes

I have implemented TreeView with Checkboxes from here I shows perfectly well. Now I am wondering to get list of selected/checked items from the tree. I believe I need to code a recursive method. But the author has set the recursive method GetTree() to be Static and I can't get any clue to start the recursion. Similar article is also found here, I found in a way for my problem overe there also, but couldn't get any thing helpful.

I am attaching whole code here for your reference :

    public class TreeViewModel : INotifyPropertyChanged
{
    public TreeViewModel(string name)
    {
        Name = name;
        Children = new List<TreeViewModel>();
    }

    #region Properties

    public string Name { get; private set; }
    public List<TreeViewModel> Children { get; private set; }
    public bool IsInitiallySelected { get; private set; }

    bool? _isChecked = false;
    TreeViewModel _parent;

    #region IsChecked

    public bool? IsChecked
    {
        get { return _isChecked; }
        set { SetIsChecked(value, true, true); }
    }

    void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
    {
        if (value == _isChecked) return;

        _isChecked = value;

        if (updateChildren && _isChecked.HasValue) Children.ForEach(c => c.SetIsChecked(_isChecked, true, false));

        if (updateParent && _parent != null) _parent.VerifyCheckedState();

        NotifyPropertyChanged("IsChecked");
    }

    void VerifyCheckedState()
    {
        bool? state = null;

        for (int i = 0; i < Children.Count; ++i)
        {
            bool? current = Children[i].IsChecked;
            if (i == 0)
            {
                state = current;
            }
            else if (state != current)
            {
                state = null;
                break;
            }
        }

        SetIsChecked(state, false, true);
    }

    #endregion

    #endregion

    void Initialize()
    {
        foreach (TreeViewModel child in Children)
        {
            child._parent = this;
            child.Initialize();
        }
    }

    public static List<TreeViewModel> setTree(TreeViewModel tree)
    {
        List<TreeViewModel> treeView = new List<TreeViewModel>();
        treeView.Add(tree);
        tree.Initialize();

        return treeView;
    }

    public static List<TreeViewModel> SetTree(string topLevelName)
    {
        List<TreeViewModel> treeView = new List<TreeViewModel>();
        TreeViewModel tv = new TreeViewModel(topLevelName);

        treeView.Add(tv);

        //Perform recursive method to build treeview 

        #region Test Data
        //Doing this below for this example, you should do it dynamically 
        //***************************************************
        TreeViewModel tvChild4 = new TreeViewModel("Child4");

        tv.Children.Add(new TreeViewModel("Child1"));
        tv.Children.Add(new TreeViewModel("Child2"));
        tv.Children.Add(new TreeViewModel("Child3"));
        tv.Children.Add(tvChild4);
        tv.Children.Add(new TreeViewModel("Child5"));

        TreeViewModel grtGrdChild2 = (new TreeViewModel("GrandChild4-2"));

        tvChild4.Children.Add(new TreeViewModel("GrandChild4-1"));
        tvChild4.Children.Add(grtGrdChild2);
        tvChild4.Children.Add(new TreeViewModel("GrandChild4-3"));

        grtGrdChild2.Children.Add(new TreeViewModel("GreatGrandChild4-2-1"));
        //***************************************************
        #endregion

        tv.Initialize();

        return treeView;
    }

    public static List<string> GetTree()
    {
        List<string> selected = new List<string>();

        //select = recursive method to check each tree view item for selection (if required)

        return selected;

        //***********************************************************
        //From your window capture selected your treeview control like:   TreeViewModel root = (TreeViewModel)TreeViewControl.Items[0];
        //                                                                List<string> selected = new List<string>(TreeViewModel.GetTree());
        //***********************************************************
    }

    #region INotifyPropertyChanged Members

    void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

I couldn't find appropriate to se the tree dynamically from my code using SetTree(string topLevelName) method, hence I added setTree(TreeViewModel tree) method to suit my needs.

Can anyone please help me to implement GetTree() method to get list of items that is checked. If an item of the tree is selected, the TreeViewModel's IsChecked property is set to true. So IsChecked can be used to find if the item is selected r not.

1

1 Answers

3
votes

To get all checked node in your tree below and including a certain node, call the following GetCheckedItems method on that node:

private IEnumerable<TreeViewModel> GetCheckedItems(TreeViewModel node)
{
    var checkedItems = new List<TreeViewModel>();

    ProcessNode(node, checkedItems);

    return checkedItems;
}    

private void ProcessNode(TreeViewModel node, IEnumerable<TreeViewModel> checkedItems)
{
    foreach (var child in node.Children)
    {
        if (child.IsChecked)
            checkedItems.Add(child);

        ProcessNode(child, checkedItems);
    }
}