如何以WPF样式将绑定路径传递给DataTrigger?

时间:2012-05-07 07:16:31

标签: wpf binding datatrigger

我有几种风格,在绑定路径上只有一点点差异:

<Style TargetType="FrameworkElement" x:Key="FieldValidationErrorStyle">
    <Setter Property="Visibility" Value="Visible" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=FieldValidationError}" Value="">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
    </Style.Triggers>
</Style>
<Style TargetType="FrameworkElement" x:Key="NumberValidationErrorStyle">
    <Setter Property="Visibility" Value="Visible" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=NumberValidationError}" Value="">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
    </Style.Triggers>
</Style>
<Style TargetType="FrameworkElement" x:Key="TextValidationErrorStyle">
    <Setter Property="Visibility" Value="Visible" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=TextValidationError}" Value="">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
    </Style.Triggers>
</Style>
<Style TargetType="FrameworkElement" x:Key="DateTimeValidationErrorStyle">
    <Setter Property="Visibility" Value="Visible" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=DateTimeValidationError}" Value="">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
    </Style.Triggers>
</Style>
<Style TargetType="FrameworkElement" x:Key="DateValidationErrorStyle">
    <Setter Property="Visibility" Value="Visible" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=DateValidationError}" Value="">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
    </Style.Triggers>
</Style>
<Style TargetType="FrameworkElement" x:Key="TimeValidationErrorStyle">
    <Setter Property="Visibility" Value="Visible" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=TimeValidationError}" Value="">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
    </Style.Triggers>
</Style>

我们可以发现样式之间的唯一区别是{Binding Path=xyz}中的DataTrigger,我可以仅使用XMAL标记删除重复吗?我知道我们可以创建custom styles as in this question但是setter是硬编码的 - 我们只能扩展DataTrigger吗?

2 个答案:

答案 0 :(得分:0)

好像你想为DataTrigger创建一个模板。由于您无法设置DataTriggers的样式,因此您必须创建自己的样式:

    public class CollapsingDataTrigger : DataTrigger
    {
        public CollapsingDataTrigger()
        {
            base.Setters.Add(new Setter(FrameworkElement.VisibilityProperty, Visibility.Collapsed));
        }
    }

然后更新您的XAML以使用此CollapsingDataTrigger而不是常规的(您必须引用此创建的命名空间)。

答案 1 :(得分:0)

您可以使用带有MultiBinding DataTrigger和OR转换器的单一样式。

<Window.Resources>
    <local:AtleastOneEmptyConverter x:Key="AtleastOneEmptyConverter"/>
    <Style TargetType="{x:Type FrameworkElement}">
        <Setter Property="Visibility" Value="Visible" />
        <Style.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding
                        Converter="{StaticResource AtleastOneEmptyConverter}">
                        <Binding Path="FieldValidationError"/>
                        <Binding Path="NumberValidationError"/>
                        <Binding Path="TextValidationError"/>
                        ...
                        <Binding Path="DateTimeValidationError"/>
                    </MultiBinding>
                </DataTrigger.Binding>
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
     </Style>
</Window.Resources>

代码背后:

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

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

我建议,跳过将样式应用于应用程序中的所有框架元素。如果应用程序GUI在将来变得复杂并且寻求替代方法(例如WPF的Validation Model),它可能会使您的应用程序GUI变慢。

如果您仍想在应用程序中将样式应用于所有类型的框架元素,那么您可以交替探索应用程序中所有框架元素的覆盖样式的App.xaml方式......