Я знаю, что это старый вопрос, но он все еще актуален для меня.
В моем случае я думал, что 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
s, когда приложение маленькое:
...А вот количество загруженных TreeViewItem
s, когда приложение находится в полноэкранном режиме (оно продолжается дальше этого фрагмента, но вы поняли идею):
Теперь осталось только стилизовать вещи, чтобы вложенный слой выглядел так, как я хочу!
Редактировать: я только что убедился, что TreeView
виртуализирует все свои слои, а не только первый слой.
person
Matt Thomas
schedule
16.03.2017