Search code examples
c#xamltreeviewwinui-3

I want to display checkboxes only the top level items the treeview using SelectionMode


I set the TreeViewSelectionMode to "Single" and "Multiple". It doesn't display top-level checkboes. Is this option not available?

Please check the image. enter image description here

  • TreeView x:Name="FileTree" SelectionMode="Single"
  • TreeView x:Name="FileTree" SelectionMode="Multiple"

enter image description here


Solution

  • One way to do this is by "hiding" the CheckBox. You can target the items using a DataTemplateSelector. Check this sample code:

    Items.cs

    using System.Collections.Generic;
    
    namespace TreeViewTest;
    
    public interface IItem
    {
        string Text { get; set; }
    }
    
    public class ParentItem : IItem
    {
        public string Text { get; set; } = string.Empty;
    
        public List<IItem>? Children { get; set; }
    }
    
    public class ChildItem : IItem
    {
        public string Text { get; set; } = string.Empty;
    }
    

    TreeViewDataTemplateSelector.cs

    using Microsoft.UI.Xaml.Controls;
    using Microsoft.UI.Xaml;
    using System;
    
    namespace TreeViewTest;
    
    public class TreeViewDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate? ParentItemTemplate { get; set; }
    
        public DataTemplate? ChildItemTemplate { get; set; }
    
        protected override DataTemplate? SelectTemplateCore(object item)
        {
            return item switch
            {
                ParentItem => ParentItemTemplate,
                ChildItem => ChildItemTemplate,
                _ => throw new NotSupportedException(),
            };
        }
    }
    

    MainPage.xaml.cs

    using Microsoft.UI.Xaml.Controls;
    using System.Collections.Generic;
    
    namespace TreeViewTest;
    
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
    
            Items.Add(new ParentItem()
            {
                Text = "Test tree1",
                Children = new List<IItem>()
                {
                    new ChildItem() {Text = "Test tree1 child" },
                    new ChildItem() {Text = "Test tree1 child2" },
                }
            });
    
            Items.Add(new ParentItem()
            {
                Text = "Test tree2",
                Children = new List<IItem>()
                {
                    new ChildItem() {Text = "Test tree2 child" },
                    new ChildItem() {Text = "Test tree2 child2" },
                }
            });
    
            Items.Add(new ParentItem()
            {
                Text = "Test tree3",
                Children = new List<IItem>()
                {
                    new ChildItem() {Text = "Test tree3 child" },
                    new ChildItem() {Text = "Test tree3 child2" },
                }
            });
        }
    
        public List<IItem> Items { get; set; } = new();
    }
    

    MainPage.xaml

    <Page
        x:Class="TreeViewTest.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="using:TreeViewTest"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
        mc:Ignorable="d">
    
        <Page.Resources>
            <DataTemplate
                x:Key="ParentItemTemplate"
                x:DataType="local:ParentItem">
                <TreeViewItem
                    Content="{x:Bind Text, Mode=OneWay}"
                    ItemsSource="{x:Bind Children, Mode=OneWay}" />
            </DataTemplate>
    
            <DataTemplate
                x:Key="ChildItemTemplate"
                x:DataType="local:ChildItem">
                <TreeViewItem Content="{x:Bind Text, Mode=OneWay}">
                    <TreeViewItem.Resources>
                        <Style TargetType="CheckBox">
                            <Setter Property="IsEnabled" Value="False" />
                            <Setter Property="Opacity" Value="0.0" />
                        </Style>
                    </TreeViewItem.Resources>
                </TreeViewItem>
            </DataTemplate>
    
            <local:TreeViewDataTemplateSelector
                x:Key="TreeViewDataTemplateSelector"
                ChildItemTemplate="{StaticResource ChildItemTemplate}"
                ParentItemTemplate="{StaticResource ParentItemTemplate}" />
        </Page.Resources>
    
        <TreeView
            ItemTemplateSelector="{StaticResource TreeViewDataTemplateSelector}"
            ItemsSource="{x:Bind Items, Mode=OneWay}"
            SelectionMode="Multiple" />
    </Page>