В простейшем master-detail сценарии, нажатие на определенный элемент в ItemsControl'е вызывает отображение детальной информации об этом элементе на другом control'е. К примеру, программа может отображать список имен покупателей, и клик по определенному покупателю приведет к тому, что в TextBlock'ах отобразится адрес, телефонный номер и дата рождения этого покупателя.
В этом посте я буду использовать солнечную систему с планетами как источник данных: клик по названию планеты в ListBox'е приведет к тому, что на ContentControl'е отобразится изображение планеты и информация о ней. ListBox играет роль мастера, а ContentControl представляет детальную информацию.
В секции ресурсов у класса Window имеется XmlDataProvider с данными планеты и CollectionViewSource, у которого свойство Source связано с provider'ом. Этот код связывает ListBox с CollectionViewSource'ом:
Мне так же нужен ContentControl, который будет использоваться для отображения детальной информации о выбранном элементе. Код ниже может сначала показаться немного странным: мы связываем ContentControl (который отображает один элемент) с коллекцией элементов? (Заметьте, что это связывание такое же, как у ListBox'а выше.) Этот код отлично работает, потому что data binding engine достаточно умен, чтобы найти различие между этими двумя целями. Когда происходит связывание ItemsControl'а с коллекцией, мы получаем коллекцию; когда происходит связывание ContentControl'а с коллекцией, мы получаем текущий (current) элемент коллекции. Все это делает применение master-detail сценария в WPF очень простым.
Чтобы определить, как в ContentControl'е должна отображаться детальная информация, мы используем DataTemplate. Следующий код описывает наиболее интересные части этого шаблона. Заметьте, что связывание происходит с XML, поэтому я использую XPath вместо Path:
Вот скриншот завершенного примера:
Здесь вы можете найти проект для Visual Studio с кодом, который был использован в статье.
В этом посте я буду использовать солнечную систему с планетами как источник данных: клик по названию планеты в ListBox'е приведет к тому, что на ContentControl'е отобразится изображение планеты и информация о ней. ListBox играет роль мастера, а ContentControl представляет детальную информацию.
В секции ресурсов у класса Window имеется XmlDataProvider с данными планеты и CollectionViewSource, у которого свойство Source связано с provider'ом. Этот код связывает ListBox с CollectionViewSource'ом:
- <!– master –>
- <ListBox ItemsSource=”{Binding Source={StaticResource cvs}}” DisplayMemberPath=”@Name” Padding=”5″ Margin=”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 очень простым.
- <!– detail –>
- <ContentControl ContentTemplate=”{StaticResource detailTemplate}” Content=”{Binding Source={StaticResource cvs}}”/>
* This source code was highlighted with Source Code Highlighter.
Чтобы определить, как в ContentControl'е должна отображаться детальная информация, мы используем DataTemplate. Следующий код описывает наиболее интересные части этого шаблона. Заметьте, что связывание происходит с XML, поэтому я использую XPath вместо Path:
- <DataTemplate x:Key=”detailTemplate”>
- (…)
- <Image Source=”{Binding XPath=Image, Converter={StaticResource stringToImageSource}}” />
- (…)
- <StackPanel Orientation=”Horizontal” Margin=”5,5,5,0?>
- <TextBlock Text=”Orbit: ” FontWeight=”Bold” />
- <TextBlock Text=”{Binding XPath=Orbit}” />
- </StackPanel>
- <StackPanel Orientation=”Horizontal” Margin=”5,0,5,0?>
- <TextBlock Text=”Diameter: ” FontWeight=”Bold”/>
- <TextBlock Text=”{Binding XPath=Diameter}” />
- </StackPanel>
- <StackPanel Orientation=”Horizontal” Margin=”5,0,5,5?>
- <TextBlock Text=”Mass: ” FontWeight=”Bold”/>
- <TextBlock Text=”{Binding XPath=Mass}” />
- </StackPanel>
- (…)
- </DataTemplate>
* This source code was highlighted with Source Code Highlighter.
Вот скриншот завершенного примера:
Здесь вы можете найти проект для Visual Studio с кодом, который был использован в статье.