Search code examples
c#wpfxamltreeviewdatatemplate

How to access DataTemplate item from target type in wpf


<TreeView x:Name="foldersItem">
        <TreeView.Resources>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="HeaderTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <CheckBox Name="cbItem"></CheckBox>
                                <TextBlock Text="{Binding}" Margin="5,0" />
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.Resources>
    </TreeView>

Basically what I have in the code above, is a TreeView, and each TreeViewItem will have a check box and a text block. How can I access, to check or uncheck, the checkbox for each TreeViewItem? I'm guessing I'll need some sort of binding, but I can't wrap my mind around what or how. The end result should have a Windows Forms type of TreeView with the checkboxes set to true false or null respectively.

If I'm going about this all wrong, please, let me know. If you need any more information, I'd be happy to provide.


Solution

  • You can set or get the value of CheckBox by a typical data binding pattern for ItemsControl. The following is a minimum example.

    Code behind:

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Windows;
    
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            public ObservableCollection<ItemViewModel> Items { get; } =
                new ObservableCollection<ItemViewModel>
                {
                    new ItemViewModel { Name = "Item1", IsChecked = null },
                    new ItemViewModel { Name = "Item2", IsChecked = true },
                    new ItemViewModel { Name = "Item3", IsChecked = false }
                };
        }
    
        public class ItemViewModel : INotifyPropertyChanged
        {
            public string Name { get; set; }
    
            private bool? _isChecked;
            public bool? IsChecked
            {
                get { return _isChecked; }
                set
                {
                    _isChecked = value;
                    OnPropertyChanged(nameof(IsChecked));
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName) =>
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    Xaml:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            x:Name="WindowRoot"
            Title="MainWindow" Height="300" Width="400">
        <Grid>
            <TreeView ItemsSource="{Binding ElementName=WindowRoot, Path=Items}">
                <TreeView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox IsChecked="{Binding IsChecked}"/>
                            <TextBlock Text="{Binding Name}"/>
                        </StackPanel>
                    </DataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </Grid>
    </Window>
    

    Access IsChecked property of ItemViewModel to set or get the value of CheckBox.