我有几种风格,在绑定路径上只有一点点差异:
<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吗?
答案 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方式......