消除重复的 DataTrigger 逻辑

Posted

技术标签:

【中文标题】消除重复的 DataTrigger 逻辑【英文标题】:Eliminate duplicate DataTrigger logic 【发布时间】:2017-05-30 14:23:04 【问题描述】:

我有一个状态栏,它通过数据绑定和触发器显示用户是否连接到服务器。我设计了两个不同的元素来实现这一点:实际的 StatusBarItem 设置彩色背景(红色、绿色、黄色),以及内部的 TextBlock 以显示文本(“未连接”、“已连接”等)。在 XAML 中执行此操作时,我必须跨两种样式复制 DataTrigger 逻辑(以更新一种样式的背景和另一种样式的文本),如下所示:

<StatusBarItem Grid.Column="0" HorizontalAlignment="Left" Padding="10,0,10,0">
    <StatusBarItem.Style>
        <Style TargetType="StatusBarItem">
            <Setter Property="Background" Value="Red" />
            <Style.Triggers>
                <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.NotConnected">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>
                <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.Connected">
                    <Setter Property="Background" Value="Green" />
                </DataTrigger>
                <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.OfflineMode">
                    <Setter Property="Background" Value="Goldenrod" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StatusBarItem.Style>
    <TextBlock Width="Auto" Height="Auto">
        <TextBlock.Style>
            <Style TargetType="TextBlock">
                <Setter Property="Text" Value="Not Connected" />
                <Setter Property="Foreground" Value="White" />
                <Style.Triggers>
                    <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.NotConnected">
                        <Setter Property="Text" Value="Not Connected" />
                    </DataTrigger>
                    <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.Connected">
                        <Setter Property="Text" Value="Connected to Perforce" />
                    </DataTrigger>
                    <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.OfflineMode">
                        <Setter Property="Text" Value="Offline Mode" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</StatusBarItem>

问题:有没有办法压缩这段代码而不复制 DataTrigger 逻辑?

请注意,我对使 TextBlock 填充整个 StatusBarItem 的解决方案不感兴趣。 当然,这将解决这个特定问题(我只需为两种背景颜色设置 TextBlock 的样式和文字)。但它并没有解决整个问题(必须在两个地方更新的重复代码)。

【问题讨论】:

【参考方案1】:

在这种特殊情况下,您可以使用 StatusBarItem 样式中的 DataTriggers 设置 Content 属性,而不是使用显式 TextBlock 作为 Content:

<StatusBarItem Grid.Column="0" HorizontalAlignment="Left" Padding="10,0,10,0">
    <StatusBarItem.Style>
        <Style TargetType="StatusBarItem">
            <Setter Property="Background" Value="Red" />
            <Setter Property="Content" Value="Not Connected" />
            <Style.Triggers>
                <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.NotConnected">
                    <Setter Property="Background" Value="Red" />
                    <Setter Property="Content" Value="Not Connected" />
                </DataTrigger>
                <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.Connected">
                    <Setter Property="Background" Value="Green" />
                    <Setter Property="Content" Value="Connected to Perforce" />
                </DataTrigger>
                <DataTrigger Binding="Binding Path=ConnectionStatus" Value="x:Static local:EConnectionStatus.OfflineMode">
                    <Setter Property="Background" Value="Goldenrod" />
                    <Setter Property="Content" Value="Offline mode" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StatusBarItem.Style>
</StatusBarItem>

另一种选择是为 StatusBarItem 定义您自己的自定义 ControlTemplate 并使用 ControlTemplate.Triggers 在一个位置更改背景和文本。

【讨论】:

谢谢。这肯定有助于解决此处发布的特定问题,但该解决方案并没有提供一种消除所有一般意义上的重复触发代码的解决方案(如上所述,这是我真正想要的东西)。是的,在这里我可以摆脱 TextBlock 并直接在 StatusBarItem 中设置文本。我可以编写一个自定义控件(对于这种情况,这是一个很好的、更通用的想法)。但是,当两个完全不相关的元素中存在相同的触发逻辑时,我该怎么办?我必须复制/粘贴 DataTriggers 吗?这才是我想要解决的真正问题。 也就是说,我认为将这个 Q 标记为已回答并发布一个使用无法通过合并两个元素或编写单个自定义控件来解决的示例的新问题是有意义的。跨度>

以上是关于消除重复的 DataTrigger 逻辑的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 DataTrigger 设置 ContentTemplate

DataTrigger:“值”属性的复杂条件

怎么去除datatable 中一列的重复值【急】

如何将参数传递给 DataTrigger?

怎么去除datatable 中一列的重复值【急】

删除DataTable重复列,只针对删除其中的一列重复的行