WPF 树视图和复选框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2394986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:32:55  来源:igfitidea点击:

WPF TreeView and Checkbox

wpftreeviewcheckbox

提问by Nathan

How would someone go about adding check boxes to only the children of a tree view in XAML? My goal is to have a tree view where the parent is just a text block and all the children are check boxes but only one child can be checked at a time. I have no problem making the whole the tree view check boxes but I am not sure how to get what I really want Any suggestions?

有人如何将复选框仅添加到 XAML 中树视图的子级?我的目标是拥有一个树视图,其中父级只是一个文本块,所有子级都是复选框,但一次只能选中一个子级。我在整个树视图复选框中没有问题,但我不确定如何获得我真正想要的任何建议?

Thanks.

谢谢。

回答by Danil

Why don't you just do it in code? Like this:

为什么不直接用代码来做呢?像这样:

        TreeViewItem newItem = new TreeViewItem()
        {
            Header = "One"
        };

        treeViewObjects.Items.Add(newItem);

        TreeViewItem newItem1 = new TreeViewItem()
        {
            Header = new CheckBox()
            {
                Content = "Two"
            }
        };
        newItem.Items.Add(newItem1);

回答by Dan Bryant

The easiest way to do this is to shape your data so that the tree view can represent it in the way you've described. Here is an example of a minimal data structure that corresponds to your type of tree:

执行此操作的最简单方法是塑造您的数据,以便树视图可以按照您描述的方式表示它。以下是与您的树类型相对应的最小数据结构示例:

public class CheckedList
{
    public string Title { get; set; }

    public ObservableCollection<CheckedItem> Items { get; private set; }

    public CheckedList()
    {
        Items = new ObservableCollection<CheckedItem>();

        //DEBUG: Test data
        Title = "Test Title";
        Items.Add(new CheckedItem("Item 1", true));
        Items.Add(new CheckedItem("Item 2", false));
    }
}

public class CheckedItem : DependencyObject
{
    public static readonly DependencyProperty StateProperty =
        DependencyProperty.Register("StateProperty", typeof(bool), typeof(CheckedItem), new UIPropertyMetadata(false));

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("TextProperty", typeof (string), typeof (CheckedItem), new UIPropertyMetadata(string.Empty));

    public bool State
    {
        get { return (bool)GetValue(StateProperty); }
        set { SetValue(StateProperty, value); }
    }

    public string Text
    {
        get { return (string) GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public CheckedItem(string text, bool state)
    {
        Text = text;
        State = state;
    }
}

Here is XAML and code-behind for a window and tree view with data templates to represent the data as text headers with check box items:

这是带有数据模板的窗口和树视图的 XAML 和代码隐藏,用于将数据表示为带有复选框项目的文本标题:

<Window x:Class="TestApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestApp"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">

<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type  local:CheckedList}" ItemsSource="{Binding Items}">
        <TextBlock Text="{Binding Title}" />
    </HierarchicalDataTemplate>

    <DataTemplate DataType="{x:Type local:CheckedItem}">
        <CheckBox Content="{Binding Text}" IsChecked="{Binding State, Mode=TwoWay}"></CheckBox> 
    </DataTemplate>
</Window.Resources>

<Grid>
    <TreeView x:Name="ExampleTree"></TreeView>
</Grid>

The code-behind:

代码隐藏:

public partial class Window1 : Window
{
    ObservableCollection<CheckedList> _lists = new ObservableCollection<CheckedList>();

    public Window1()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        //DEBUG: Test data
        _lists.Add(new CheckedList());
        _lists.Add(new CheckedList());
        ExampleTree.ItemsSource = _lists;
    }
}

Using ObservableCollection and DependencyObject allows the tree and data structure to stay in sync. As the user clicks on items in the tree, you should be able to look at your lists and see the modifications. Alternately, if you modify the data, it should be reflected in the tree.

使用 ObservableCollection 和 DependencyObject 允许树和数据结构保持同步。当用户单击树中的项目时,您应该能够查看您的列表并查看修改。或者,如果您修改数据,它应该反映在树中。