WPF TreeView 和 Checkbox

5

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

谢谢。

3个回答

8
为什么不直接用代码实现呢?像这样:

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

        treeViewObjects.Items.Add(newItem);

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

2
简单而高效。谢谢。 - eslyverano
嗨,它可以工作,但只适用于子项目。如何将复选框添加到父项目? - Anti Mafia
子级使用:new CheckBox(),而父级仅使用文本,在父级中添加 CheckBox。 - Danil

7

5

最简单的方法是通过整理数据,使得树形视图能够以你所描述的方式呈现它。以下是一个最小数据结构示例,与你的树型结构相对应:

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

以下是用XAML和代码后台实现的窗口和树形视图,使用数据模板将数据表示为带有复选框项的文本标题:
以下是窗口和树形视图的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>

代码后端:

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

使用ObservableCollection和DependencyObject可以让树形结构和数据结构保持同步。当用户在树中点击项目时,您应该能够查看列表并看到修改。或者,如果您修改了数据,则应在树中反映出来。

我刚注意到您只希望每次仅检查一项。 如果是这样,您可以修改 CheckedList 来侦听 CheckedItem.State 的更改并执行您的规则。 您可能希望考虑使用单选按钮而不是复选框,因为大多数用户将期望复选框允许多个选择。 - Dan Bryant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接