在 WPF 中使用多重绑定简化 style.triggers
Simplifying style.triggers with mulitibinding in WPF
在回顾我多年前写的一些代码时,我在我的 WPF 样式部分遇到了这个触发器。可以看出,我使用对 Checkin、Checkout 和 NotSeen 的完全相同的引用调用 MultiBinding Converter 7 次以生成 7 种不同的颜色。这让我觉得非常多余并且 space 消耗。一定有更好的办法。
有没有办法用更短的样式来完成这个?另外,他们是在 MVVM 框架中完全避免使用 MultiBinding Converter 的方法吗?可以使用附加行为来代替这个吗?
TIA
<Style.Triggers>
<!-- if checkout is null, then check for waiting time from the checkin value. Setter action occurs for DataTrigger Value -->
<DataTrigger Value="1" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource VioletBrush}" />
</DataTrigger>
<DataTrigger Value="2" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource BlueBrush}" />
</DataTrigger>
<DataTrigger Value="3" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource TurquoiseBrush}" />
</DataTrigger>
<DataTrigger Value="4" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource GreenBrush}" />
</DataTrigger>
<DataTrigger Value="5" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource YellowBrush}" />
</DataTrigger>
<DataTrigger Value="6" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource OrangeBrush}" />
</DataTrigger>
<DataTrigger Value="7" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource RedBrush}" />
</DataTrigger>
</Style.Triggers>
使用自定义 DataTrigger 的第一种方法
创建自定义 DataTrigger class,您可以在其中以编程方式定义其绑定,但在代码中设置 Setter.
class DataTriggerBinding : DataTrigger
{
public DataTriggerBinding()
{
SetBinding();
}
private void SetBinding()
{
var multiBinding = new MultiBinding();
multiBinding.Bindings.Add(new Binding("CheckIn"));
multiBinding.Bindings.Add(new Binding("CheckOut"));
multiBinding.Bindings.Add(new Binding("NotSeen"));
multiBinding.Converter = new WaitStatus();
this.Binding = multiBinding;
}
}
XAML:
<Label Content="{Binding Age}">
<Label.Style>
<Style TargetType="Label">
<Style.Triggers>
<local:DataTriggerBinding Value="1">
<Setter Property="Foreground" Value="Red"/>
</local:DataTriggerBinding>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
使用附加行为的后一种方法
class DataTriggerBinding : DependencyObject
{
public static readonly DependencyProperty IsCustomBindingProperty = DependencyProperty.RegisterAttached(
"CustomBinding", typeof(bool), typeof(DataTriggerBinding), new PropertyMetadata((x, y) =>
{
SetBinding((DataTrigger)x);
}));
public static void SetIsCustomBinding(DependencyObject element, bool value)
{
element.SetValue(IsCustomBindingProperty, value);
}
public static bool GetIsCustomBinding(DependencyObject element)
{
return (bool)element.GetValue(IsCustomBindingProperty);
}
private static void SetBinding(DataTrigger dataTrigger)
{
var multiBinding = new MultiBinding();
multiBinding.Bindings.Add(new Binding("CheckIn"));
multiBinding.Bindings.Add(new Binding("CheckOut"));
multiBinding.Bindings.Add(new Binding("NotSeen"));
multiBinding.Converter = new WaitStatus();
dataTrigger.Binding = multiBinding;
}
}
XAML:
<DataTrigger local:DataTriggerBinding.IsCustomBinding="True" Value="1">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
在回顾我多年前写的一些代码时,我在我的 WPF 样式部分遇到了这个触发器。可以看出,我使用对 Checkin、Checkout 和 NotSeen 的完全相同的引用调用 MultiBinding Converter 7 次以生成 7 种不同的颜色。这让我觉得非常多余并且 space 消耗。一定有更好的办法。
有没有办法用更短的样式来完成这个?另外,他们是在 MVVM 框架中完全避免使用 MultiBinding Converter 的方法吗?可以使用附加行为来代替这个吗?
TIA
<Style.Triggers>
<!-- if checkout is null, then check for waiting time from the checkin value. Setter action occurs for DataTrigger Value -->
<DataTrigger Value="1" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource VioletBrush}" />
</DataTrigger>
<DataTrigger Value="2" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource BlueBrush}" />
</DataTrigger>
<DataTrigger Value="3" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource TurquoiseBrush}" />
</DataTrigger>
<DataTrigger Value="4" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource GreenBrush}" />
</DataTrigger>
<DataTrigger Value="5" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource YellowBrush}" />
</DataTrigger>
<DataTrigger Value="6" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource OrangeBrush}" />
</DataTrigger>
<DataTrigger Value="7" >
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource WaitStatus}">
<Binding Path="CheckIn" />
<Binding Path="CheckOut" />
<Binding Path="NotSeen" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="{StaticResource RedBrush}" />
</DataTrigger>
</Style.Triggers>
使用自定义 DataTrigger 的第一种方法
创建自定义 DataTrigger class,您可以在其中以编程方式定义其绑定,但在代码中设置 Setter.
class DataTriggerBinding : DataTrigger
{
public DataTriggerBinding()
{
SetBinding();
}
private void SetBinding()
{
var multiBinding = new MultiBinding();
multiBinding.Bindings.Add(new Binding("CheckIn"));
multiBinding.Bindings.Add(new Binding("CheckOut"));
multiBinding.Bindings.Add(new Binding("NotSeen"));
multiBinding.Converter = new WaitStatus();
this.Binding = multiBinding;
}
}
XAML:
<Label Content="{Binding Age}">
<Label.Style>
<Style TargetType="Label">
<Style.Triggers>
<local:DataTriggerBinding Value="1">
<Setter Property="Foreground" Value="Red"/>
</local:DataTriggerBinding>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
使用附加行为的后一种方法
class DataTriggerBinding : DependencyObject
{
public static readonly DependencyProperty IsCustomBindingProperty = DependencyProperty.RegisterAttached(
"CustomBinding", typeof(bool), typeof(DataTriggerBinding), new PropertyMetadata((x, y) =>
{
SetBinding((DataTrigger)x);
}));
public static void SetIsCustomBinding(DependencyObject element, bool value)
{
element.SetValue(IsCustomBindingProperty, value);
}
public static bool GetIsCustomBinding(DependencyObject element)
{
return (bool)element.GetValue(IsCustomBindingProperty);
}
private static void SetBinding(DataTrigger dataTrigger)
{
var multiBinding = new MultiBinding();
multiBinding.Bindings.Add(new Binding("CheckIn"));
multiBinding.Bindings.Add(new Binding("CheckOut"));
multiBinding.Bindings.Add(new Binding("NotSeen"));
multiBinding.Converter = new WaitStatus();
dataTrigger.Binding = multiBinding;
}
}
XAML:
<DataTrigger local:DataTriggerBinding.IsCustomBinding="True" Value="1">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>