如何结合我看似多余的XAML

时间:2009-10-29 21:48:50

标签: wpf datatemplate

我有8个不同的XAML DataTemplates都非常相似。以下是其中两个:

<DataTemplate x:Key="ConflictFieldStringCellContentTemplate">
    <StackPanel>
        <TextBlock Text="{Binding ClientVersion.Value}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}" />
        <Label Background="LightGray" Height="1" Margin="0, 4, -4, 2"></Label>
        <TextBlock Text="{Binding ServerVersion.Value}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}"/>
    </StackPanel>
</DataTemplate>

<DataTemplate x:Key="ConflictFieldStringArrayCellContentTemplate">
    <StackPanel>
        <TextBlock Text="{Binding ClientVersion.Value, Converter={StaticResource stringArrayToCommaDelimitedStringConverter}}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}"/>
        <Label Background="LightGray" Height="1" Margin="0, 4, -4, 2"></Label>
        <TextBlock Text="{Binding ServerVersion.Value, Converter={StaticResource stringArrayToCommaDelimitedStringConverter}}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}"/>
    </StackPanel>
</DataTemplate>

正如您所看到的,唯一的区别是它们使用不同的Converter来绑定TextBlock的Text属性。我有什么方法可以分解这两个DataTemplates的共性吗?我还有6个并且更新它们变得非常乏味,因为除了用于绑定Text属性的Converter之外,一切都是相同的。

有没有办法以某种方式将这个因素分解为一个可以某种方式参数化的模板?像这样的东西会很酷(伪代码):

<DataTemplate x:Key="BaseCellContentTemplate">
    <StackPanel>
        <TextBlock Text="{??}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}" />
        <Label Background="LightGray" Height="1" Margin="0, 4, -4, 2"></Label>
        <TextBlock Text="{Binding ServerVersion.Value}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}"/>
    </StackPanel>
</DataTemplate>

<DataTemplate x:Key="ConflictFieldStringCellContentTemplate" BaseTemplate="BaseCellContentTemplate">
    <??>{Binding ClientVersion.Value}</??>
</DataTemplate>

<DataTemplate x:Key="ConflictFieldStringArrayCellContentTemplate" BaseTemplate="BaseCellContentTemplate">

    <??>{Binding ClientVersion.Value, Converter={StaticResource stringArrayToCommaDelimitedStringConverter}}</??>
</DataTemplate>

2 个答案:

答案 0 :(得分:2)

您可以尝试的一条路径是创建新的User Control

此用户控件应包含StackPanel,此StackPanel应包含TextBox,Label和TextBox。

您可以将TextConverters实现为依赖项属性。

最终的DataTemplates集如下所示:

    <DataTemplate x:Key="ConflictFieldStringCellContentTemplate">    
       <local:VersionDisplayControl 
                  ClientVersionTextConverter="{StaticResource stringArrayToCommaDelimitedStringConverter}" />
    </DataTemplate>

   <DataTemplate x:Key="ConflictFieldStringArrayCellContentTemplate">
       <local:VersionDisplayControl 
          ClientVersionTextConverter="{StaticResource stringArrayToCommaDelimitedStringConverter}"
          ServerVersionTextConverter="{StaticResource stringArrayToCommaDelimitedStringConverter}" />
    </DataTemplate>

这假设用户控件能够从某些全局可用的源访问源版本信息。 如果没有, VersionDisplayControl 将必须公开另一个公共属性,可能称为 VersionSource

答案 1 :(得分:2)

如果只有一个值,并且您希望纯粹使用模板执行此操作,则可以执行以下操作:

<DataTemplate x:Key="VersionDisplayTemplate">
    <StackPanel>
        <TextBlock Text="{TemplateBinding Tag}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}" />
        <Label Background="LightGray" Height="1" Margin="0, 4, -4, 2"></Label>
        <TextBlock Text="{TemplateBinding Content}"
                   Foreground="{Binding Path=Mismatch, Converter={StaticResource mismatchBoolToBrushConverter}}"/>
    </StackPanel>
</DataTemplate>

现在您可以将其用作:

<DataTemplate x:Key="ConflictFieldStringCellContentTemplate">    
   <ContentPresenter 
       Tag="ABC"
       Content="{Binding ClientVersion.Value}" 
       ContentTemplate="{StaticResource VersionDisplayTemplate}" 
       />
</DataTemplate>

<DataTemplate x:Key="ConflictFieldStringArrayCellContentTemplate">
   <ContentPresenter 
       Tag="XYZ"
       Content="{Binding ClientVersion.Value, Converter={StaticResource stringArrayToCommaDelimitedStringConverter}}" 
       ContentTemplate="{StaticResource VersionDisplayTemplate}"
       />
</DataTemplate>