Я знаю, что это старый вопрос, но он все еще был актуален для меня.
В моем случае я подумал, что TreeView
не обрежет его, потому что мне нужно ровно два слоя, а типы отображаемых элементов различны для двух слоев. Кроме того, я рефакторинг списка Expander
с, поэтому я думал более одномерный.
Но потом я понял, что вы можете настроить ItemTemplate
из TreeView
, чтобы включить свой собственный HierarchicalDataTemplate
, и что вы можете настроить ItemTemplate
этого HierarchicalDataTemplate
с вашим собственным DataTemplate
. .. Престо! Ровно два слоя с разными вещами в каждом!
Так что я хочу сказать, что TreeView
достаточно гибок, чтобы вы не пытались создать свой собственный элемент управления.
Вот что я сделал:
XAML:
<Page x:Class="Foo.Views.TreePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Foo.Views"
xmlns:viewModel="clr-namespace:Foo.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Tree page"
d:DataContext="{d:DesignInstance Type=viewModel:TreeModel}">
<TreeView
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="True"
VirtualizingPanel.ScrollUnit="Pixel"
ItemsSource="{Binding Values}"><!-- IList<Person> -->
<TreeView.ItemTemplate><!-- Template for first layer, which has a HierarchicalDataTemplate so that this layer will expand -->
<HierarchicalDataTemplate
ItemsSource="{Binding Expenses}"><!-- IList<Expense> -->
<HierarchicalDataTemplate.ItemTemplate><!-- Template for the second layer, which has a DataTemplate instead of HierarchicalDataTemplate so that this layer won't expand -->
<DataTemplate>
<TextBlock Text="{Binding Amount}"/><!-- Expense amount in dollars -->
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<TextBlock Text="{Binding Name}"/><!-- Person name -->
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Page>
Класс Person
:
public class Person
{
public string Name { get; set; }
public List<Expense> Expenses { get; set; }
}
Класс Expense
:
public class Expense
{
public double Amount { get; set; }
}
Вот как это выглядит:
Я проверил это с помощью Snoop , чтобы доказать, что это виртуализация пользовательского интерфейса. Вот количество загруженных TreeViewItem
с, когда приложение маленькое:
... А вот количество загруженных TreeViewItem
с, когда приложение работает в полноэкранном режиме (оно продолжает выходить за рамки этого фрагмента, но вы понимаете):
Теперь достаточно просто стилизовать вещи так, чтобы вложенный слой выглядел так, как я хочу!
Редактировать: я только что проверил, что TreeView
виртуализирует все его слои, а не только первый слой.