windows 一个数据模板中的多个TreeViewItem

bzzcjhmw  于 2023-01-31  发布在  Windows
关注(0)|答案(1)|浏览(115)

我在我的WinUI应用程序中遇到了TreeView问题,我希望在一个DataTemplate中有几个TreeViewItem。
我已经尝试了几种方法,但我可以想象我可以做一些类似于我的例子。但在我运行的代码中,我只能看到文本块和树视图项标题,但现在在树视图项处有箭头。

<Window
    x:Class="SimpleTreeViewExample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SimpleTreeViewExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <Grid.Resources>
            <DataTemplate x:Key="PersonTemplate" x:DataType="local:Person">
                <StackPanel>
                    <TextBlock Text="{x:Bind FirstName}" />
                    <TextBlock Text="{x:Bind LastName}" />

                    <TreeViewItem ItemsSource="{x:Bind Books}" IsExpanded="False" Content="Books"/>
                </StackPanel>
            </DataTemplate>

            <DataTemplate x:Key="BookTemplate" x:DataType="local:Book">
                <StackPanel>
                    <TextBlock Text="{x:Bind Writer}" />
                    <TextBlock Text="{x:Bind Title}" />
                </StackPanel>
            </DataTemplate>

            <local:TemplateSelector x:Key="TemplateSelector"
                PersonTemplate="{StaticResource PersonTemplate}"
                BookTemplate="{StaticResource BookTemplate}">
                
            </local:TemplateSelector>

        </Grid.Resources>

        <StackPanel>
            <TreeView x:Name="PackageReferenceTree"
                            ItemsSource="{x:Bind Persons}" 
                            ItemTemplateSelector="{StaticResource TemplateSelector}" />
        </StackPanel>
    </Grid>
</Window>

下面是我的代码:

public sealed partial class MainWindow : Window
{
    public ObservableCollection<Person> Persons = new();
        
    public MainWindow()
    {
        this.InitializeComponent();
        Person person1 = new Person("John", "Doe");
        person1.Books.Add(new Book("Stephen King", "The Shining"));
        Persons.Add(person1);
    }
}

public partial class Person : ObservableObject
{
    [ObservableProperty]
    private string firstName;

    [ObservableProperty]
    private string lastName;

    public ObservableCollection<Book> Books = new();

    public Person(string firstName, string lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

public partial class Book : ObservableObject
{
    [ObservableProperty]
    private string writer;

    [ObservableProperty]
    private string title;

    public Book(string writer, string title)
    {
        this.writer = writer;
        this.title = title;
    }
}

public class TemplateSelector : DataTemplateSelector
{
    public DataTemplate PersonTemplate { get; set; }

    public DataTemplate BookTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        if (item.GetType() == typeof(Person))
        {
            return PersonTemplate;
        }
        else if (item.GetType() == typeof(Book))
        {
            return BookTemplate;
        }
 
        throw new NotSupportedException($"The item type: {item.GetType()} wasn't known ");
    }
}

如果我删除了StackPanel,只保留了一个TreeViewItem,它可以正常工作。我有一个模板选择器,当我有一个StackPanel时,它没有被命中,但它在没有StackPanel的情况下被命中,所以我假设这个问题与此相关。
因此,我想得到的是我有一个人的列表,每个人都可以展开。展开时,他们包含一个名和一个姓,一个书籍列表和一个电影列表。书籍和电影列表也可以展开,并且不是同一类型。
它看起来像这样:

ojsjcaue

ojsjcaue1#

这里是一个示例供您参考,您需要更改代码中Name的值。代码来自the official sample,您需要根据需要更改模型(人员,书籍,电影)。

    • 主窗口. xaml**
<Grid>
    <TreeView ItemsSource="{x:Bind DataSource}">
        <TreeView.ItemTemplate>
            <DataTemplate x:DataType="local:ExplorerItem">
                <TreeViewItem ItemsSource="{x:Bind Children}" Content="{x:Bind Name}">
                </TreeViewItem>
            </DataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>
    • 主窗口. xaml. cs**
public sealed partial class MainWindow : Window
{
    TreeViewNode personalFolder;
    TreeViewNode personalFolder2;
    private ObservableCollection<ExplorerItem> DataSource;
    public MainWindow()
    {
        this.InitializeComponent();
        DataSource = GetData();
        
    }

    private ObservableCollection<ExplorerItem> GetData()
    {
        var list = new ObservableCollection<ExplorerItem>();
        ExplorerItem folder1 = new ExplorerItem()
        {
            Name = "Persons",
            Type = ExplorerItem.ExplorerItemType.Folder,
            Children =
            {
                new ExplorerItem()
                {
                    Name = "John",
                    Type = ExplorerItem.ExplorerItemType.File,
                },
                new ExplorerItem()
                {
                    Name = "Doe",
                    Type = ExplorerItem.ExplorerItemType.File,
                },
                new ExplorerItem()
                {
                    Name = "Books",
                    Type = ExplorerItem.ExplorerItemType.Folder,
                    Children =
                    {
                        new ExplorerItem()
                        {
                            Name = "Title",
                            Type = ExplorerItem.ExplorerItemType.File,
                        },
                        new ExplorerItem()
                        {
                            Name = "Writer",
                            Type = ExplorerItem.ExplorerItemType.File,
                        }

                    }
                },
                new ExplorerItem()
                {
                    Name = "Movies",
                    Type = ExplorerItem.ExplorerItemType.Folder,
                    Children =
                    {
                        new ExplorerItem()
                        {
                            Name = "Production",
                            Type = ExplorerItem.ExplorerItemType.File,
                        },
                        new ExplorerItem()
                        {
                            Name = "Year",
                            Type = ExplorerItem.ExplorerItemType.File,
                        },
                        new ExplorerItem()
                        {
                            Name = "Score",
                            Type = ExplorerItem.ExplorerItemType.File,
                        }

                    }
                }

            }
        };
        ExplorerItem folder2 = new ExplorerItem()
        {
            Name = "Personal Folder",
            Type = ExplorerItem.ExplorerItemType.Folder,
            Children =
                    {
                        new ExplorerItem()
                        {
                            Name = "Home Remodel Folder",
                            Type = ExplorerItem.ExplorerItemType.Folder,
                            Children =
                            {
                                new ExplorerItem()
                                {
                                    Name = "Contractor Contact Info",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                },
                                new ExplorerItem()
                                {
                                    Name = "Paint Color Scheme",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                },
                                new ExplorerItem()
                                {
                                    Name = "Flooring Woodgrain type",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                },
                                new ExplorerItem()
                                {
                                    Name = "Kitchen Cabinet Style",
                                    Type = ExplorerItem.ExplorerItemType.File,
                                }
                            }
                        }
                    }
        };

        list.Add(folder1);
        list.Add(folder2);
        return list;
    }

}

public class ExplorerItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public enum ExplorerItemType { Folder, File };
    public string Name { get; set; }
    public ExplorerItemType Type { get; set; }
    private ObservableCollection<ExplorerItem> m_children;
    public ObservableCollection<ExplorerItem> Children
    {
        get
        {
            if (m_children == null)
            {
                m_children = new ObservableCollection<ExplorerItem>();
            }
            return m_children;
        }
        set
        {
            m_children = value;
        }
    }

    private bool m_isExpanded;
    public bool IsExpanded
    {
        get { return m_isExpanded; }
        set
        {
            if (m_isExpanded != value)
            {
                m_isExpanded = value;
                NotifyPropertyChanged("IsExpanded");
            }
        }
    }

    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

class ExplorerItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate FolderTemplate { get; set; }
    public DataTemplate FileTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        var explorerItem = (ExplorerItem)item;
        return explorerItem.Type == ExplorerItem.ExplorerItemType.Folder ? FolderTemplate : FileTemplate;
    }
}

相关问题