Практическое руководство. Выполнение привязки к коллекции и вывод сведений в зависимости от выделенного элемента

В простом сценарии с основными сведениями у вас есть привязка к данным ItemsControl, например ListBox. На основе выбора пользователя отображаются дополнительные сведения о выбранном элементе. В этом примере показано, как реализовать этот сценарий.

Пример

В этом примере People представляет собой ObservableCollection<T> классов Person. Этот класс Person содержит три свойства: FirstName, LastName и HomeTown, все они типа string.

<Window x:Class="SDKSample.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:SDKSample"
  Title="Binding to a Collection"
  SizeToContent="WidthAndHeight">
  <Window.Resources>
    <local:People x:Key="MyFriends"/>
  </Window.Resources>

  <StackPanel>
    <TextBlock FontFamily="Verdana" FontSize="11"
               Margin="5,15,0,10" FontWeight="Bold">My Friends:</TextBlock>
    <ListBox Width="200" IsSynchronizedWithCurrentItem="True"
             ItemsSource="{Binding Source={StaticResource MyFriends}}"/>
    <TextBlock FontFamily="Verdana" FontSize="11"
               Margin="5,15,0,5" FontWeight="Bold">Information:</TextBlock>
    <ContentControl Content="{Binding Source={StaticResource MyFriends}}"
                    ContentTemplate="{StaticResource DetailTemplate}"/>
  </StackPanel>
</Window>

ContentControl использует следующее DataTemplate, определяющее, как представлена информация о объекте Person:

<DataTemplate x:Key="DetailTemplate">
  <Border Width="300" Height="100" Margin="20"
          BorderBrush="Aqua" BorderThickness="1" Padding="8">
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
      </Grid.ColumnDefinitions>
      <TextBlock Grid.Row="0" Grid.Column="0" Text="First Name:"/>
      <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=FirstName}"/>
      <TextBlock Grid.Row="1" Grid.Column="0" Text="Last Name:"/>
      <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=LastName}"/>
      <TextBlock Grid.Row="2" Grid.Column="0" Text="Home Town:"/>
      <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=HomeTown}"/>
    </Grid>
  </Border>
</DataTemplate>

Ниже приведен снимок экрана примера. В ContentControl отображаются другие свойства выбранного человека.

Binding to a collection

Ниже указаны два аспекта, на которые следует обратить внимание в этом примере:

  1. ListBox и ContentControl привязаны к одному и тому же источнику. Свойства Path обеих привязок не указаны, так как оба элемента управления привязаны ко всему объекту коллекции.

  2. Чтобы это свойство работало, необходимо задать для IsSynchronizedWithCurrentItem значение true. Задание значения этого свойства гарантирует, что выбранный элемент всегда задан как CurrentItem. Как вариант, если ListBox получает данные из CollectionViewSource, он автоматически синхронизирует выделение и валюту.

Обратите внимание, что класс Person переопределяет метод ToString следующим образом. По умолчанию ListBox вызывает ToString и отображает строковое представление каждого объекта в связанной коллекции. Вот почему каждый Person отображается как имя в ListBox.

public override string ToString()
{
    return firstname.ToString();
}
Public Overrides Function ToString() As String
    Return Me._firstname.ToString
End Function

См. также