WPF Binding: Master-detail сценарий.

Автор оригинала: Beatriz Costa
  • Перевод
В простейшем master-detail сценарии, нажатие на определенный элемент в ItemsControl'е вызывает отображение детальной информации об этом элементе на другом control'е. К примеру, программа может отображать список имен покупателей, и клик по определенному покупателю приведет к тому, что в TextBlock'ах отобразится адрес, телефонный номер и дата рождения этого покупателя.

В этом посте я буду использовать солнечную систему с планетами как источник данных: клик по названию планеты в ListBox'е приведет к тому, что на ContentControl'е отобразится изображение планеты и информация о ней. ListBox играет роль мастера, а ContentControl представляет детальную информацию.

В секции ресурсов у класса Window имеется XmlDataProvider с данными планеты и CollectionViewSource, у которого свойство Source связано с provider'ом. Этот код связывает ListBox с CollectionViewSource'ом:
  1. <!– master –>
  2. <ListBox ItemsSource=”{Binding Source={StaticResource cvs}}” DisplayMemberPath=”@NamePadding=”5Margin=”0,0,5,0/>
* This source code was highlighted with Source Code Highlighter.

Мне так же нужен ContentControl, который будет использоваться для отображения детальной информации о выбранном элементе. Код ниже может сначала показаться немного странным: мы связываем ContentControl (который отображает один элемент) с коллекцией элементов? (Заметьте, что это связывание такое же, как у ListBox'а выше.) Этот код отлично работает, потому что data binding engine достаточно умен, чтобы найти различие между этими двумя целями. Когда происходит связывание ItemsControl'а с коллекцией, мы получаем коллекцию; когда происходит связывание ContentControl'а с коллекцией, мы получаем текущий (current) элемент коллекции. Все это делает применение master-detail сценария в WPF очень простым.
  1. <!– detail –>
  2. <ContentControl ContentTemplate=”{StaticResource detailTemplate}” Content=”{Binding Source={StaticResource cvs}}”/>
* This source code was highlighted with Source Code Highlighter.

Чтобы определить, как в ContentControl'е должна отображаться детальная информация, мы используем DataTemplate. Следующий код описывает наиболее интересные части этого шаблона. Заметьте, что связывание происходит с XML, поэтому я использую XPath вместо Path:
  1. <DataTemplate x:Key=”detailTemplate>
  2.   (…)
  3.   <Image Source=”{Binding XPath=Image, Converter={StaticResource stringToImageSource}}” />
  4.   (…)
  5.   <StackPanel Orientation=”HorizontalMargin=”5,5,5,0?>
  6.     <TextBlock Text=”Orbit:FontWeight=”Bold/>
  7.     <TextBlock Text=”{Binding XPath=Orbit}” />
  8.   </StackPanel>
  9.   <StackPanel Orientation=”HorizontalMargin=”5,0,5,0?>
  10.     <TextBlock Text=”Diameter:FontWeight=”Bold/>
  11.     <TextBlock Text=”{Binding XPath=Diameter}” />
  12.   </StackPanel>
  13.   <StackPanel Orientation=”HorizontalMargin=”5,0,5,5?>
  14.     <TextBlock Text=”Mass:FontWeight=”Bold/>
  15.     <TextBlock Text=”{Binding XPath=Mass}” />
  16.   </StackPanel>
  17.   (…)
  18. </DataTemplate>
* This source code was highlighted with Source Code Highlighter.

Вот скриншот завершенного примера:


Здесь вы можете найти проект для Visual Studio с кодом, который был использован в статье.
  • +12
  • 6,5k
  • 3
Поделиться публикацией

Похожие публикации

Комментарии 3

  • НЛО прилетело и опубликовало эту надпись здесь
      +1
      Если вы привяжите второй контрол к первому — будет, точнее датасоурс может быть тот же, а вот привязать слеюует свойство SelectedItem = "{Binding ElementName=firstList,Path=SelectedItem}"
      +1

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое