Treeview与复选框绑定不同的列表

时间:2011-09-29 08:45:17

标签: wpf treeview

我有一个这样的课程:

public class Project
{
List<Object> list1;
List<Object> list2;
}

我想在树视图控件中显示如下:

Checkbox + "Listing1"
--> Checkbox + Object 1 of list1
--> Checkbox + Object 2 of list1
Checkbox + "Listing2"
--> Checkbox + Object 1 of list2
-->Checkbox + Object 2 of list2

我最大的问题是区分2个列表+一些额外的:如果list2不包含任何对象,则可能不会显示“Listing2”标题。

有没有人知道我该怎么做?

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

您可以通过扩展TreeViewItem类来创建一个类TreeViewItemWithCheckbox,如下所示:

public class TreeViewItemWithCheckbox : TreeViewItem
    {
        #region Variable Declaration

        CheckBox chkBox = new CheckBox();
        StackPanel stpContent = new StackPanel();

        #endregion

        #region Properties

        public string HeaderText
        {
            get { return chkBox.Content.ToString(); }
            set { chkBox.Content = value; }
        }

        public bool IsChecked
        {
            get { return chkBox.IsChecked.Value; }
            set { chkBox.IsChecked = value; }
        }

        #endregion

        #region Constructor

        public TreeViewItemWithCheckbox()
        {
            stpContent.Orientation = Orientation.Horizontal;

            chkBox = new CheckBox();
            chkBox.VerticalAlignment = VerticalAlignment.Center;
            chkBox.Click += new RoutedEventHandler(SetCheckboxes);
            chkBox.Margin = new Thickness(0, 0, 0, 0);
            stpContent.Children.Add(chkBox);

            Header = stpContent;
        }

        #endregion

        #region Event Handlers

        private void SetCheckboxes(object sender, RoutedEventArgs e)
        {
            TreeViewItemWithCheckbox selectedItem = ((TreeViewItemWithCheckbox)((StackPanel)((CheckBox)sender).Parent).Parent);

            if (selectedItem != null)
            {
                /* Set checkboxes for all child items */
                if (selectedItem.Items.Count > 0)
                {
                    SetChildItemCheckboxes(selectedItem, selectedItem.IsChecked);
                }

                /* Check if all childs checked then check/uncheck parent accoringly */
                if (selectedItem.Parent.GetType() == typeof(TreeViewItemWithCheckbox))
                {
                    TreeViewItemWithCheckbox parentItem = (TreeViewItemWithCheckbox)selectedItem.Parent;

                    bool bIsAllChecked = true;
                    foreach (TreeViewItemWithCheckbox item in parentItem.Items)
                    {
                        if (!item.IsChecked)
                        {
                            bIsAllChecked = false;
                            break;
                        }
                    }
                    parentItem.IsChecked = bIsAllChecked;
                }
            }
        }

        private void SetChildItemCheckboxes(TreeViewItemWithCheckbox item, bool IsChecked)
        {
            if (item.Items.Count > 0)
            {
                foreach (TreeViewItemWithCheckbox childItem in item.Items)
                {
                    SetChildItemCheckboxes(childItem, IsChecked);
                    item.IsChecked = IsChecked;
                }
            }
            else
                item.IsChecked = IsChecked;
        }

        #endregion
    }

然后你需要添加2个列表中的树视图节点,如下所示:

trvTest.Items.Clear();

//Add default root element
TreeViewItemWithCheckbox rootNode = new TreeViewItemWithCheckbox();
rootNode.HeaderText = "Root";
rootNode.IsExpanded = true;
trvTest.Items.Add(rootNode);

if (_project.list1.Count > 0)
{
    TreeViewItemWithCheckbox nodeHead1 = new TreeViewItemWithCheckbox();
    nodeHead1.HeaderText = "Listing 1";
    rootNode.Items.Add(nodeHead1);

    TreeViewItemWithCheckbox node1;
    for (int i = 0; i < _project.list1.Count; i++)
    {
       node1 = new TreeViewItemWithCheckbox();
       node1.HeaderText = _project.list1[i].Name;
       nodeHead1.Items.Add(node1);
    }
}

if (_project.list2.Count > 0)
{
    TreeViewItemWithCheckbox nodeHead2 = new TreeViewItemWithCheckbox();
    nodeHead2.HeaderText = "Listing 2";
    rootNode.Items.Add(nodeHead2);

    TreeViewItemWithCheckbox node2 = new TreeViewItemWithCheckbox();
    for (int i = 0; i < _project.list2.Count; i++)
    {
       node2 = new TreeViewItemWithCheckbox();
       node2.HeaderText = _project.list2[i].Name;
       nodeHead2.Items.Add(node2);
    }
}

答案 2 :(得分:1)

如果您的第一个“列表”项目是静态的,您可以执行类似这样的操作

<TreeView x:Name="tv">
    <TreeViewItem Header="Listing 1" ItemsSource="{Binding list1}"/>
    <TreeViewItem Header="Listing 2" ItemsSource="{Binding list2}"/>
</TreeView>

要隐藏没有孩子的元素,您需要一些代码。

var view = CollectionViewSource.GetDefaultView(_project.list1);
view.Filter = myFilter;
view.Refresh();

tv.DataContext = _project;

当然,对于这两个列表。