c# - 在 WPF 中重用触发条件或多重绑定(bind)

标签 c# .net wpf binding controltemplate

目标是在不同的地方重用这个多重绑定(bind)

<MultiTrigger.Conditions>
    <Condition Value="True">
        <Condition.Binding>
                <MultiBinding Converter="{StaticResource ValidationBooleanConverter}">
                    <Binding X" />
                    <Binding Y" />
                    <Binding Z" />        
                </MultiBinding>
        </Condition.Binding>
    </Condition>
</MultiTrigger.Conditions>

当前不太DRY条件(n+)

<Style x:Key="AnErrorTemplate" TargetType="FrameworkElement">
 <Style.Triggers>
    <MultiTrigger>
         <!-- Repeating the whole MultiTrigger.Conditions block here ---> 
         <Setter Property="Validation.ErrorTemplate" Value="{StaticResource DirtyErrorControlTemplate}" />
    </MultiTrigger>
 </Style.Triggers>

<Style x:Key="AnotherStyle" TargetType="FrameworkElement">
 <Style.Triggers>
    <MultiTrigger>
         <!-- Repeating the whole MultiTrigger.Conditions block here ---> 
         <Setter Property="Other" Value="SomeValueIfTheSameConditionsAreTrue" />
    </MultiTrigger>
 </Style.Triggers>

事实上,要求更广泛,因为我还需要在 ControlTemplates 中重复使用这些相同的条件。

<ControlTemplate x:Key="InlineErrorControlTemplate" TargetType="{x:Type Control}">
    <TextBlock Text="{Binding ElementName=InputView, Path=(Validation.Errors)[0].ErrorContent}" Foreground="Red"/>
     <ControlTemplate.Triggers>
         <MultiTrigger>
            <!-- Repeating the whole MultiTrigger.Conditions block here ---> 
            <Setter Property="Visibility" Value="SetMeIfTheseSameTriggerConditionsHold" />
        </MultiTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

方便维护的雨伞?

有什么想法可以让我只指定一次 MultiTrigger.Conditions 或 MultiBinding,然后在多种样式和控件模板中使用它吗?

  • 仅在 XAML 中?

最佳答案

这正是 Style inheritance 的原因在 WPF 中提供。另外,在您的情况下,我建议使用 DataTriggerMultiBinding而不是MultiTriggerMultiBinding ...

为了演示这一点,假设我正在创建一个样式来检查 Tooltip 是否或Name分配给任何FrameworkElement是空的。如果是这样,它将生成 Foreground红色如果 FrameworkElementComboBox或其 Background黄色如果FrameworkElementTextBox .

我正在使用杂项字段TagFrameworkElement ....

因此,全 XAML(加上 C# 转换器)解决方案如下...

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Height="300" Width="300">
    <Window.Resources>
        <local:AtleastOneEmptyConverter x:Key="AtleastOneEmptyConverter"/>
        <Style x:Key="BaseFrameworkElementStyle"
               TargetType="{x:Type FrameworkElement}">
            <Style.Triggers>
                <DataTrigger Value="True">
                    <DataTrigger.Binding>
                      <MultiBinding
                      Converter="{StaticResource AtleastOneEmptyConverter}">
                            <Binding Path="ToolTip"
                                     RelativeSource="{RelativeSource Self}"/>
                            <Binding Path="Name"
                                     RelativeSource="{RelativeSource Self}"/>
                        </MultiBinding>
                    </DataTrigger.Binding>
                    <Setter Property="Tag" Value="1"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="ApplyToComboStyle"
               TargetType="{x:Type ComboBox}"
               BasedOn="{StaticResource BaseFrameworkElementStyle}">
            <Style.Triggers>
                <DataTrigger
                    Binding="{Binding Tag,
                            RelativeSource={RelativeSource Self}}" Value="1">
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="ApplyToTextBoxStyle"
               TargetType="{x:Type TextBox}"
               BasedOn="{StaticResource BaseFrameworkElementStyle}">
            <Style.Triggers>
                <DataTrigger
                    Binding="{Binding Tag,
                            RelativeSource={RelativeSource Self}}" Value="1">
                    <Setter Property="Background" Value="Yellow"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <ComboBox Style="{StaticResource ApplyToComboStyle}"
                  x:Name="NotRedComboBox"
                  ToolTip="You will not see red text here">
            <ComboBoxItem IsSelected="True">I am not Red!</ComboBoxItem>
        </ComboBox>
        <ComboBox Style="{StaticResource ApplyToComboStyle}">
            <ComboBoxItem IsSelected="True">I am Red!</ComboBoxItem>
        </ComboBox>
        <Separator Margin="5"/>
        <TextBox Style="{StaticResource ApplyToTextBoxStyle}"
                 Text="I am yellow"
                 x:Name="YellowTextBox"/>
        <TextBox Style="{StaticResource ApplyToTextBoxStyle}"
                 Text="I am not yellow"
                 x:Name="NotYellowTextBox"
                 ToolTip="You will not see yellow background here"/>
    </StackPanel>
</Window>

C# 转换器:

public class AtleastOneEmptyConverter : IMultiValueConverter
{
    public object Convert
        (object[] values, Type targetType,
         object parameter, CultureInfo culture)
    {
        return values.Cast<string>().Any(val => string.IsNullOrEmpty(val));
    }

    public object[] ConvertBack
        (object value, Type[] targetTypes,
        object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

关于c# - 在 WPF 中重用触发条件或多重绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10606407/

相关文章:

wpf - 如何在 Visual Studio 2010 中为数值数组创建自定义图像装饰插件?

c# - Unity 5 音频音量 slider

c# - MySql 异常 : Connection need to valid and open. C#

c# - 如何在 XAML WPF 中创建强制依赖属性

c# - 为什么 VSTO Word ContentControl 没有 Name 属性?

c# - 当绑定(bind)到 WPF DataGrid 时,包装的 ObservableCollection<T> 抛出 `' EditItem' is not allowed for this view`

空条件运算符和等待的 C# 错误

c# - 如何创建、读取和写入 XML C# windows 窗体?

.net - 在 WPF 字体大小和 "standard"字体大小之间转换

c# - 如何从字符中添加字符