问题
It seems to me that there is a major difference between the Blend-style Trigger
s found in the Interactivity namespace, and the classic Trigger
s available via Styles, ControlTemplate
s, etc, in WPF (I supposed this probably applies to SilverLight as well).
In WPF, when you set a Trigger
with a Setter, you get two behaviours: if the trigger condition is met, the Setter is applied. However, once a Trigger is no longer satisfied, the previous value is restored. This is tremendously useful when programming UI.
I've tried to code a DataTrigger
similarly using the Blend way: I applied ChangePropertyAction to my control, and have it trigger off of Interactivity DataTrigger
using a Binding to my ViewModel.
<Rectangle x:Name="SecondaryHighlightBackground" Fill="#FF505050">
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding IsHighlighted}" Value="Value">
<ei:ChangePropertyAction PropertyName="Opacity" Value="0.5"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
...
</Rectangle>
So this worked as expected... except I was stunned to discover that when I flip the IsHighlighted value to false, that the original Opacity of 0% is not restored (I set that lower down). To double check this, I wrote this example to verify:
<Window x:Class="TestWpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480">
<Grid x:Name="LayoutRoot">
<Button Name="button1"
Width="173"
Height="57"
Margin="10,10,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Content" Value="foo" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=button1}" Value="True">
<Setter Property="Content" Value="bar" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
The expected behaviour is that if you if mouse over the button, the content changes to 'bar'. Moving the mouse away restores content to 'Foo', as specified by the Style. The style sets the Content to avoid the property precedence issue.
My question is: Is two-way triggering really just missing in the Blend extensions, or is there a way to enable this somehow?
Am I missing something? I thought that was the very point of triggers, that they have this two-way functionality. I would like to continue using the Blend interactivity actions because I find them useful and intuitive, but this kind of thing forces me back into coding XAML by hand.
回答1:
If I understand correctly you just have to provide the consideration for the other value in your trigger as well since it won't do it by default as you've taken control of that condition. Something like;
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding IsHighlighted}" Value="True">
<ei:ChangePropertyAction PropertyName="Opacity" Value="0.5"/>
</ei:DataTrigger>
<ei:DataTrigger Binding="{Binding IsHighlighted}" Value="False">
<ei:ChangePropertyAction PropertyName="Opacity" Value="0"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
回答2:
Yes, you have to put both conditions with this Blend triggers, there is no return to default. On the other side with Blend Triggers you can CallMethodAction and that can be very useful with animations. Also with Blend triggers you have ControlStoryBoard action, and much more, but in your described case you are better with "normal" triggers.
来源:https://stackoverflow.com/questions/15258199/blend-trigger-vs-wpf-trigger