Элемент ListBox позволяет легко установить привязку к коллекции объектов, однако по умолчанию каждый элемент ListBox отображает строку. Если же нам необходимо отобразить более сложные объекты в ListBox, то для этого надо использовать объект DataTemplate.
Ключевым свойством для отображения данных во всех элементах-списках (не только в ListBox) является свойство ItemTemplate. Оно задает шаблон данных. В качестве значения этого свойства устанавливается объект DataTemplate - именно этот объект и управляет отображением данных.
В качестве самих данных, которые отображаются в DataTemplate, как правило, выступают объекты пользовательских классов, создаваемых самим разработчиком. Например, определим в проекте следующий класс Phone, который будет представлять модель телефона:
public class Phone { public int Id { get; set; } public string Title { get; set; } // модель телефона public string Company { get; set; } // производитель public string ImagePath { get; set; } // путь к изображению }
Далее создадим в классе MainPage свойство, которое будет представлять коллекцию смартфонов:
using System; using System.Collections.Generic; using Windows.UI.Xaml.Controls; namespace DataApp { public sealed partial class MainPage : Page { public List<Phone> Phones { get; set; } public MainPage() { this.InitializeComponent(); Phones = new List<Phone> { new Phone {Id=1, ImagePath="/Assets/iphone6s.jpg", Title="iPhone 7", Company="Apple" }, new Phone {Id=2, ImagePath="/Assets/mate8.jpg", Title="Huawei P10", Company="Huawei" }, new Phone {Id=3, ImagePath="/Assets/nexus5x.jpg", Title="Pixel", Company="Google" }, new Phone {Id=4, ImagePath="/Assets/galaxys6.jpg", Title="Galaxy S8", Company="Samsung"} }; } private async void phonesList_SelectionChanged(object sender, SelectionChangedEventArgs e) { Phone selectedPhone = (Phone)phonesList.SelectedItem; await new Windows.UI.Popups.MessageDialog($"Выбран {selectedPhone.Title}").ShowAsync(); } } }
Здесь создается 4 объекта Phone. Для каждого объекта устанавливаются необходимые значения. Причем свойство ImagePath
указывает на
путь к изображению в папке Assets. Предполагается, что в папке Assets есть четыре изображения для каждой из моделей.
Теперь изменим разметку MainPage.xaml:
<Page x:Class="DataApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:DataApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <ListBox Name="phonesList" ItemsSource="{x:Bind Phones}" SelectionChanged="phonesList_SelectionChanged"> <ListBox.ItemTemplate> <DataTemplate x:DataType="local:Phone"> <StackPanel Margin="10"> <Image Width="100" Height="80" Source="{x:Bind ImagePath}" /> <TextBlock FontSize="16" Text="{x:Bind Title}" HorizontalAlignment="Center" /> <TextBlock FontSize="16" Text="{x:Bind Company}" HorizontalAlignment="Center" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Page>
С помощью атрибута ItemsSource="{x:Bind Phones}"
задаем привязку к свойству Phones из MainPage. А с помощью свойства ListBox.ItemTemplate
задаем, как этот список Phones будет отображаться.
Элемент DataTemplate устанавливает, как будет отображаться один элемент Phone из списка Phones. Чтобы создать привязку именно к объекту Phone, в
DataTemplate устанавливается атрибут x:DataType="data:Phone"
. То есть префикс data
указывает на то пространство имен, в
котором определен класс Phone. После этой установки мы можем задать привязку у вложенных элементов к конкретным свойствам класса Phone:
<Image Width="200" Height="150" Source="{x:Bind ImagePath}" />
А с помощью атрибута SelectionChanged="phonesList_SelectionChanged"
устанавливается обработчик выделения элементов. Определим в классе MainPage этот обработчик:
private async void phonesList_SelectionChanged(object sender, SelectionChangedEventArgs e) { Phone selectedPhone = (Phone)phonesList.SelectedItem; await new Windows.UI.Popups.MessageDialog($"Выбран {selectedPhone.Title}").ShowAsync(); }
Мы можем получить выделенный элемент через свойство phonesList.SelectedItem
. И так как DataTemplate отображает объекты Phone, то выделенный элемент
мы можем привести к типу Phone.
В итоге получится следующее приложение: