xaml
Шаблоны данных
Поиск…
Использование DataTemplate в ListBox
Предположим, что у нас есть следующий фрагмент XAML:
<ListBox x:Name="MyListBox" />
Затем в коде для этого файла XAML мы пишем в конструкторе следующее:
MyListBox.ItemsSource = new[]
{
1, 2, 3, 4, 5
};
Запустив приложение, мы получим список номеров, которые мы ввели.
Однако, если мы попытаемся отобразить список объектов пользовательского типа, например
MyListBox.ItemsSource = new[]
{
new Book { Title = "The Hitchhiker's Guide to the Galaxy", Author = "Douglas Adams" },
new Book { Title = "The Restaurant at the End of the Universe", Author = "Douglas Adams" },
new Book { Title = "Life, the Universe and Everything", Author = "Douglas Adams" },
new Book { Title = "So Long, and Thanks for All the Fish", Author = "Douglas Adams" },
new Book { Title = "Mostly Harmless", Author = "Douglas Adams" }
};
предполагая, что у нас есть класс под названием « Book
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
}
то список будет выглядеть примерно так:
Хотя мы можем предположить, что ListBox будет «достаточно умным», чтобы отображать наши объекты книги в самый раз, мы фактически видим полное имя типа Book . Что на самом деле делает ListBox, это вызов встроенного метода ToString() для объектов, которые он хочет отобразить, и, хотя это дает желаемый результат в случае чисел, вызов ToString() на объектах пользовательских классов приводит к получению имени их тип, как видно на скриншоте.
Мы могли бы решить это, написав ToString() для нашего книжного класса, т. Е.
public override string ToString()
{
return Title;
}
Однако это не очень гибко. Что делать, если мы хотим отобразить автора? Мы могли бы написать это и в ToString , но что, если мы не хотим, чтобы во всех списках в приложении? Как насчет красивой обложки книги?
Это поможет DataTemplates. Они являются фрагментами XAML, которые могут быть «созданы» по мере необходимости, заполнены деталями в соответствии с исходными данными, для которых они созданы. Проще говоря, если мы расширим наш код ListBox следующим образом:
<ListBox x:Name="MyListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
то список создаст TextBox для каждого элемента в своем источнике, и те TextBox будут иметь свои свойства Text заполненные «со значениями» из свойства Title наших объектов.
Если мы запустим приложение сейчас, мы получим тот же результат, что и выше, * даже если мы удалим пользовательскую реализацию ToString . Что выгодно в этом, так это то, что мы можем настроить этот шаблон намного дальше возможностей простой string (и ToString ). Мы можем использовать любой элемент XAML, который мы хотим, включая пользовательские, и можем «привязать» их значения к фактическим данным из наших объектов (например, Title в примере выше). Например, расширьте шаблон следующим образом:
<ListBox x:Name="MyListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock FontStyle="Italic" Text="{Binding Author}" />
<TextBlock FontSize="18" Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Затем мы получаем хороший формат наших книг!



