WPF TreeView HierarchicalDataTemplate

<TreeView ItemsSource="{Binding BooksGroupList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Books}">
            <TextBlock Text="{Binding GroupName}" FontWeight="Bold"/>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <StackPanel.Resources>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="FontSize" Value="20"/>
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="FontSize" Value="30"/>
                                        <Setter Property="FontWeight" Value="ExtraBold"/>
                                        <Setter Property="Foreground" Value="Red"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </StackPanel.Resources>
                        <TextBlock Text="{Binding GroupName}" Width="150"/>
                        <TextBlock Text="{Binding Id}" Width="30"/>
                        <TextBlock Text="{Binding Name}" Width="140"/>
                        <TextBlock Text="{Binding Title}" Width="130"/>
                        <TextBlock Text="{Binding Author}" Width="130"/>
                        <TextBlock Text="{Binding Topic}" Width="130"/>
                        <TextBlock Text="{Binding Summary}" Width="140"/>
                        <TextBlock Text="{Binding ISBN}" Width="auto"/>
                    </StackPanel>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>


//cs
private void InitData()
{ 
    List<Book> booksList = new List<Book>();
    int idx = 0;
    for (int i = 0; i<100; i++)
    {
        ++idx;
        for (int j = 0; j<10; j++)
        {
            booksList.Add(new Book()
            {
                GroupName=$"GroupName_{idx}",
                Id=(idx).ToString(),
                Name=$"Name_{idx}_{j+1}",
                Topic=$"Topic_{idx}_{j+1}",
                Author=$"Author_{idx}_{j+1}",
                ISBN=$"ISBN_{idx}_{j+1}_{Guid.NewGuid().ToString("N")}",
                Title=$"Title_{idx}_{j+1}",
                Summary=$"Summary_{idx}_{j+1}"
            });
        }
    }

    BooksGroupList=new ObservableCollection<BookGroup>(booksList.GroupBy(x => x.GroupName)
            .Select(g => new BookGroup
            {
                GroupName=g.Key,
                Books=new ObservableCollection<Book>(g)
            }));
}

 

 

 

 

image

 

 

 

image

 

 

image

 

 

//xaml
<Window x:Class="WpfApp34.MainWindow"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp34"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TreeView ItemsSource="{Binding BooksGroupList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Books}">
                    <TextBlock Text="{Binding GroupName}" FontWeight="Bold"/>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <StackPanel.Resources>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Setter Property="FontSize" Value="20"/>
                                        <Style.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter Property="FontSize" Value="30"/>
                                                <Setter Property="FontWeight" Value="ExtraBold"/>
                                                <Setter Property="Foreground" Value="Red"/>
                                            </Trigger>
                                        </Style.Triggers>
                                    </Style>
                                </StackPanel.Resources>
                                <TextBlock Text="{Binding GroupName}" Width="150"/>
                                <TextBlock Text="{Binding Id}" Width="30"/>
                                <TextBlock Text="{Binding Name}" Width="140"/>
                                <TextBlock Text="{Binding Title}" Width="130"/>
                                <TextBlock Text="{Binding Author}" Width="130"/>
                                <TextBlock Text="{Binding Topic}" Width="130"/>
                                <TextBlock Text="{Binding Summary}" Width="140"/>
                                <TextBlock Text="{Binding ISBN}" Width="auto"/>
                            </StackPanel>
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>


//cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp34
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var vm = new MainVM();
            this.DataContext=vm;
        }
    }

    public class MainVM : INotifyPropertyChanged
    {
        public MainVM()
        {
            InitData();
        }

        private void InitData()
        { 
            List<Book> booksList = new List<Book>();
            int idx = 0;
            for (int i = 0; i<100; i++)
            {
                ++idx;
                for (int j = 0; j<10; j++)
                {
                    booksList.Add(new Book()
                    {
                        GroupName=$"GroupName_{idx}",
                        Id=(idx).ToString(),
                        Name=$"Name_{idx}_{j+1}",
                        Topic=$"Topic_{idx}_{j+1}",
                        Author=$"Author_{idx}_{j+1}",
                        ISBN=$"ISBN_{idx}_{j+1}_{Guid.NewGuid().ToString("N")}",
                        Title=$"Title_{idx}_{j+1}",
                        Summary=$"Summary_{idx}_{j+1}"
                    });
                }
            }

            BooksGroupList=new ObservableCollection<BookGroup>(booksList.GroupBy(x => x.GroupName)
                    .Select(g => new BookGroup
                    {
                        GroupName=g.Key,
                        Books=new ObservableCollection<Book>(g)
                    }));
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]string propertyName="")
        {
            var handler = PropertyChanged;
            if(handler!=null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private ObservableCollection<BookGroup> booksGroupList;
        public ObservableCollection<BookGroup> BooksGroupList
        {
            get
            {
                return booksGroupList;
            }
            set
            {
                if (value!=booksGroupList)
                {
                    booksGroupList=value;
                    OnPropertyChanged(nameof(BooksGroupList));
                }
            }
        }
    }


    public class Book
    {
        public string GroupName { get; set; }
        public string Id { get; set; }
        public string Name { get; set; }
        public string Author { get; set; }
        public string ISBN { get; set; }
        public string Title { get; set; }
        public string Summary { get; set; }
        public string Topic { get; set; }
    }


    public class BookGroup
    {
        public string GroupName { get; set; }
        public ObservableCollection<Book> Books { get; set; }
    }
}

 

posted @ 2025-08-13 17:28  FredGrit  阅读(24)  评论(0)    收藏  举报