ContentControl и CollectionView.CurrentItem - PullRequest
       2

ContentControl и CollectionView.CurrentItem

0 голосов
/ 17 февраля 2019

Ссылка на этот пример:

https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-bind-to-a-collection-and-display-information-based-on-selection

(некоторые соответствующие фрагменты кода:)

<Window.Resources>

<local:People x:Key="MyFriends"></local:People>

<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>

</Window.Resources>

<ListBox Width="200" IsSynchronizedWithCurrentItem="True"
  ItemsSource="{Binding Source={StaticResource MyFriends}}"/>

<ContentControl x:Name="contentControl1"
  Content="{Binding Source={StaticResource MyFriends}}"
  ContentTemplate="{StaticResource DetailTemplate}" />

Оба ListBox.ItemsSource и ContentControl.Content связаны с одним и тем жеsource (MyFriends, экземпляр класса People, производный от ObservableCollection<Person>).Если мое понимание верно, это означает, что оба свойства ListBox.ItemsSource и ContentControl.Content будут связаны с одним и тем же неявно созданным экземпляром ListCollectionView.

Я понимаю, что настройка ListBox.IsSynchronizedWithCurrentItem="True" синхронизирует ListBox.SelectedItemи ItemCollection.CurrentItem.

DetailTemplate (выше) отображает сведения о выбранном элементе ListBox, несмотря на то, что он «связан» с ListCollectionView.Указание Path=/ (что, по моему мнению, было бы необходимо для достижения конечного поведения) не имеет никакого эффекта - это как если бы WPF знает, как это сделать неявным образом:

<ContentControl x:Name="contentControl1"
  Content="{Binding Source={StaticResource MyFriends}, Path=/}"
  ContentTemplate="{StaticResource DetailTemplate}" />

В качестве теста я создал другойContentControl с Content привязанным к DataTemplate, содержащему ListBox:

<ContentControl x:Name="contentControl2"
  Content="{Binding Source={StaticResource MyFriends}}"
  ContentTemplate="{StaticResource DetailTemplate2}" />

<DataTemplate x:Key="DetailTemplate2">
   <ListBox ItemsSource="{Binding}"></>
</DataTemplate>

И он отобразил список.

Мой вопрос: почему DataTemplate получаетвыбранный объект Person, в то время как ListBox и DetailTemplate2 получают коллекцию People?

(поведение желательно, я просто не понимаю, какую черную магию происходит под капотом, чтобы сделатьэто так)

1 Ответ

0 голосов
/ 19 февраля 2019

Хороший вопрос!Я не заметил этого, пока не прочитал твой пост.Таким образом, после того, как вы покопались в исходном коде PropertyPathWorker, кажется, что когда PropertyPathWorker не удалось решить элемент объекта, в вашем случае он пытается решить ect «FirstName», «LastName».с помощью «MyFriends» он попытается решить проблему с помощью объекта.И если все-таки не получится, он попытается решить ее с помощью CurrentItem представления, и вот где произошло волшебство.Вы можете найти эти коды в PropertyPathWorker.UpdateSourceValueState(int k, ICollectionView collectionView, object newValue, bool isASubPropertyChange) и PropertyPathWorker.ReplaceItem(int k, object newO, object parent).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...