带CheckBox的WPF TreeView - 如何获取Checked列表?

时间:2013-12-27 11:56:11

标签: c# wpf checkbox treeview

我已使用here的复选框实现了TreeView 我表现得非常好。现在我想知道从树中获取所选/已检查项目的列表。我相信我需要编写一个递归方法。但是作者已经将递归方法GetTree()设置为静态,我无法获得任何开始递归的线索。 类似的文章也被发现here,我发现在某种程度上我的问题也很严重,但是没有任何帮助。

我在这里附上整个代码供您参考:

    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
}

我无法使用SetTree(string topLevelName)方法从我的代码中动态地查找树,因此我添加了setTree(TreeViewModel tree)方法以满足我的需要。

任何人都可以帮我实现GetTree()方法来获取已检查项目的列表。如果选择了树的项,则TreeViewModel的IsChecked属性设置为true。因此,IsChecked可用于查找是否选择了项目。

1 个答案:

答案 0 :(得分:2)

要获取树中的所有已检查节点,包括某个节点,请在该节点上调用以下 GetCheckedItems 方法:

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);
    }
}