ContentControl and CollectionView.CurrentItem



引用此示例:

https://learn.microsoft.com/en-us/dotnet/framework/wpf/wpf/data/how-to-to-bind-to-bind-to-bind-to-collection-and-collection-and-display-information-neformation-in-On-on-on-prection

(一些相关的代码段:)

<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.ItemsSourceContentControl.Content都绑定到同一源(MyFriends,源自ObservableCollection<Person>的人类类的实例)。如果我的理解是正确的,则意味着ListBox.ItemsSourceContentControl.Content属性都将绑定到ListCollectionView的隐式创建实例。

我知道设置ListBox.IsSynchronizedWithCurrentItem="True"同步ListBox.SelectedItemItemCollection.CurrentItem

DetailTemplate(上图)尽管"绑定"到ListCollectionView,但仍显示所选ListBox项目的详细信息。指定Path=/(我认为实现由此产生的行为是必要的)没有任何效果 - 好像WPF知道它会以某种方式隐含地:

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

作为测试,我创建了另一个ContentControl,其中 Content绑定到包含ListBoxDataTemplate

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

它显示了列表。

我的问题是:为什么DataTemplateListBoxDetailTemplate2获取People集合时获得所选的Person对象?

(行为是可取的,我只是不明白引擎盖下发生了什么黑魔法以使其如此)

是一个很好的问题!在阅读您的帖子之前,我没有注意到这一点。因此,从PropertyPathWorker的源代码进行了一些挖掘之后,似乎当PropertyPathWorker无法求解对象的成员时,就您的情况下,它尝试求解" firstName"," lastName" ect。使用"我的朋友",它将尝试以对象的视图来解决它。如果仍然失败,它将尝试使用View的CurrentItem解决它,这就是魔术发生的地方。您可以在PropertyPathWorker.UpdateSourceValueState(int k, ICollectionView collectionView, object newValue, bool isASubPropertyChange)PropertyPathWorker.ReplaceItem(int k, object newO, object parent)中找到这些代码。

最新更新