在属性上切换内容演示者,将完整数据上下文传递给子节点?

时间:2017-06-20 16:48:46

标签: wpf

我有以下观点。

<Window.Resources>
   <DataTemplate DataType="{x:Type search:SomeChildType1Vm}">
      <a:SomeParentType1 DataContext="{Binding}" />
   </DataTemplate>

   <DataTemplate DataType="{x:Type search:SomeChildType2Vm}">
      <a:SomeParentType2 DataContext="{Binding}" />
   </DataTemplate>
</Window.Resources>
<Grid>
   <Grid.RowDefinitions>
      <RowDefinition Height="*" />
   </Grid.RowDefinitions>
   <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*" />
   </Grid.ColumnDefinitions>

   <ContentPresenter x:Name="ContentPresenter" Content="{Binding SomeChildTypeProperty}" />
</Grid>

视图的我的datacontext是类如下的类:

public class MySpecialVm
{
    public SomeChildType SomeChildTypeProperty {get;set;}
}

public class SomeChildType1 : SomeChildType
{
...
}

public class SomeChildType2 : SomeChildType
{
...
}

public class SomeChildType
{
...
}

我想让SomeChildTypeProperty属性控件的类型由内容演示者显示哪个控件。

这可能吗?在当前格式中,传递给控件的datacontext始终是SomeChildType1或SomeChildType2,这是您可以想象的不理想。 :)

1 个答案:

答案 0 :(得分:1)

像往常一样,在提交问题后我找到了解决方案。

使用E-R diagram提供的代码示例,我能够生成以下内容。

<Window.Resources>
   <valueConverters:NullableObjectToTypeConverter
      x:Key="NullableObjectToTypeConverter" />

   <DataTemplate x:Key="SomeParentType1Template" DataType="{x:Type a:SomeParentType}">
      <a:SomeParentType1Control DataContext="{Binding}" />
   </DataTemplate>

   <DataTemplate x:Key="SomeParentType2Template" DataType="{x:Type a:SomeParentType}">
      <a:SomeParentType2Control DataContext="{Binding}" />
   </DataTemplate>

   <DataTemplate DataType="{x:Type a:SomeParentType}">
      <ContentControl Content="{Binding }">
         <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
               <Setter Property="ContentTemplate"
                       Value="{StaticResource SomeParentType1Template}" />
               <Style.Triggers>
                  <DataTrigger
                     Binding="{Binding SomeChildTypeProperty,
                     Converter={StaticResource NullableObjectToTypeConverter}}"
                     Value="{x:Type a:SomeChildType2}">
                     <Setter Property="ContentTemplate"
                             Value="{StaticResource SomeParentType2Template}" />
                  </DataTrigger>
               </Style.Triggers>
            </Style>
         </ContentControl.Style>
      </ContentControl>
   </DataTemplate>
</Window.Resources>
<Grid>
   <Grid.RowDefinitions>
      <RowDefinition Height="*" />
   </Grid.RowDefinitions>
   <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*" />
   </Grid.ColumnDefinitions>

   <ContentPresenter x:Name="ContentPresenter"
                     Content="{Binding}" />
</Grid>

这也需要一个对象来输入转换器。

public class NullableObjectToTypeConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
      return value?.GetType();
   }

   public object ConvertBack(object value, Type targetType, object parameter,
      System.Globalization.CultureInfo culture)
   {
      throw new NotImplementedException();
   }
}