如何结合我看似多余的XAML

发布于 2024-08-09 13:56:44 字数 2600 浏览 5 评论 0原文

我有 8 个不同的 XAML DataTemplate,它们都非常相似。下面是其中的 2 个:

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

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

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

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

I have 8 different XAML DataTemplates that are all very similar. Here are 2 of them:

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

As you can see, the only difference is that they use a different Converter for the Binding of the Text property of the TextBlock. Is there any way for me to factor out the commonalities of these two DataTemplates? I have 6 more and updating them is getting very tedious, because everything is identical except for the Converter for the Binding of the Text property.

Is there a way to somehow factor this out into one template which can be parameterized somehow? Something like this would be cool (pseudo-code):

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨后咖啡店 2024-08-16 13:56:44

如果只有一个值,并且您想纯粹使用模板来完成此操作,您可以这样做:

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

If there is only one value, and you want to do it purely with templates, you might do:

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

Now you can use it as:

<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>
嘿看小鸭子会跑 2024-08-16 13:56:44

您可以尝试的一种方法是创建一个新的 用户控件

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

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

最终的数据模板集如下所示:

    <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

One path you can try is to create a new User Control.

This User Control should contain the StackPanel, and this StackPanel should contain the TextBox, Label and TextBox.

You could implement the TextConverters as dependency properties.

The final set of DataTemplates would look like this:

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

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

This is assuming that the User Control is able to access the source version information from some globally available source.
If not, the VersionDisplayControl will have to expose another public property, probably called VersionSource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文