似乎我总是被最简单的东西所困扰...我有一个带有自定义bool DependencyProperty'GpoModule'的UserControl。
默认设置为false。
我在'GpoModule'= true时触发了FadeIn动画,在'GpoModule'= false时触发了FadeOut动画。
我的问题是,当加载控件时,会触发FadeOut动画,我希望仅在属性更改时触发动画(或者至少在加载时不是默认值)。我怀疑我可能要定义某种事件触发器,但我希望避免这种情况。
的DependencyProperty:
public bool GpoModule {
get { return (bool)GetValue(GpoModuleProperty); }
set { SetValue(GpoModuleProperty, value); }
}
public static readonly DependencyProperty GpoModuleProperty =
DependencyProperty.Register("GpoModule", typeof(bool),
typeof(ModuleIndicator), new UIPropertyMetadata(false));
动画:
<UserControl.Resources>
<Duration x:Key="D">0:0:0.6</Duration>
<Storyboard x:Key="SbFadeOut">
<DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Width)"
From="38" To="0"
Duration="{StaticResource D}">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Height)"
From="38"
To="0"
Duration="{StaticResource D}">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)"
From="1"
To="0"
Duration="{StaticResource D}">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Key="SbFadeIn">
<DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Width)"
From="0" To="38"
Duration="{StaticResource D}">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Height)"
From="0"
To="38"
Duration="{StaticResource D}">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)"
From="0"
To="1"
Duration="{StaticResource D}">
<DoubleAnimation.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</UserControl.Resources>
动画元素:
<Viewbox x:Name="GpoIndicator"
VerticalAlignment="Center" HorizontalAlignment="Center"
Stretch="Fill" Width="0" Height="0">
<Grid Height="38" Width="38">
<Ellipse Height="38"
Fill="{DynamicResource App.Primary.Light}"
Stroke="{DynamicResource App.Border}" />
<TextBlock Width="38"
Height="38"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontFamily="{DynamicResource AppFont}"
FontSize="30"
FontWeight="Bold"
Foreground="{DynamicResource ResourceKey=App.Accent.Secondary}"
Padding="0,2,0,0"
Text="G"
TextAlignment="Center"
TextWrapping="Wrap"/>
</Grid>
<Viewbox.Style>
<Style TargetType="Viewbox">
<Style.Triggers>
<DataTrigger Binding="{Binding GpoModule, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ModuleIndicator}}}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="GpoIn">
<Storyboard>
<StaticResource ResourceKey="SbFadeIn" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="GpoIn" />
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding GpoModule, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ModuleIndicator}}}"
Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard Name="GpoOut">
<Storyboard>
<StaticResource ResourceKey="SbFadeOut" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="GpoOut" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Viewbox.Style>
</Viewbox>
谢谢!
编辑:我应该提到还有另外两个'指标'对象/孩子 - 'RedesignIndicator'和'NovellIndicator'。每个都有各自的bool DependencyProperties。
在提出问题之前我尝试使用多个条件。我的第一次尝试是将条件设置为'IsLoaded',但没有效果。
我的第二次尝试是使用另一个Dependency属性'AnimationLocked',默认设置为true,并尝试了两个变体。
一:在属性改变回调时将AnimationLocked设置为false(这具有在其他一个子对象上触发FadeOut动画的副作用和
二:在UserControl.Loaded事件上设置AnimationLocked为false(没有效果)
答案 0 :(得分:0)
您可以使用多数据触发器:
<Viewbox.Style>
<Style TargetType="Viewbox">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsLoaded}" Value="True" />
<Condition Binding="{Binding GpoModule}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterAction>
... fade in animation
</MultiDataTrigger.EnterAction>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsLoaded}" Value="True" />
<Condition Binding="{Binding GpoModule}" Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterAction>
... fade out animation
</MultiDataTrigger.EnterAction>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Viewbox.Style>
IsLoaded
是另一个依赖项属性,在控件true
事件处理程序中设置为Loaded
。
这种方式动画只会在IsLoaded == true
时发生。
P.S。:不确定是否必须在控制IsLoaded = false
事件处理程序中设置Unloaded
。
答案 1 :(得分:0)
我最终解决的解决方案是在我的控件上为三个孩子的“模块指示器”中的每一个添加一个“AnimationLocked”bool DependencyProperty。 'AnimationLocked'的默认值为true,在'Module'bool DependencyProperty回调中设置为false,这样可以确保动画被阻止,直到第一次用户交互手动更改属性为止。我希望有一些内置的方法可以防止触发器“触发”默认值。这似乎非常不优雅,我仍然愿意接受其他建议。
UserControl代码隐藏:
public bool GpoAnimationLocked
{
get { return (bool)GetValue(GpoAnimationLockedProperty); }
set { SetValue(GpoAnimationLockedProperty, value); }
}
public static readonly DependencyProperty GpoAnimationLockedProperty =
DependencyProperty.Register("GpoAnimationLocked", typeof(bool),
typeof(ModuleIndicator), new UIPropertyMetadata(true));
public bool GpoModule {
get { return (bool)GetValue(GpoModuleProperty); }
set { SetValue(GpoModuleProperty, value); }
}
public static readonly DependencyProperty GpoModuleProperty =
DependencyProperty.Register("GpoModule", typeof(bool),
typeof(ModuleIndicator), new UIPropertyMetadata(false, GpoSelectionPropertyChanged));
protected virtual void GpoSelectionChanged(DependencyPropertyChangedEventArgs e) {
GpoAnimationLocked = false;
}
private static void GpoSelectionPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
((ModuleIndicator)sender).GpoSelectionChanged(e);
}
UserControl xaml(动画的子指标':
<Viewbox x:Name="GpoIndicator"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Stretch="Fill"
Width="0"
Height="0">
<Grid Height="38"
Width="38">
<Ellipse Height="38"
Fill="{DynamicResource App.Primary.Light}"
Stroke="{DynamicResource App.Border}" />
<TextBlock Width="38"
Height="38"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontFamily="{DynamicResource AppFont}"
FontSize="30"
FontWeight="Bold"
Foreground="{DynamicResource ResourceKey=App.Accent.Secondary}"
Padding="0,2,0,0"
Text="G"
TextAlignment="Center"
TextWrapping="Wrap" />
</Grid>
<Viewbox.Style>
<Style TargetType="Viewbox">
<Style.Triggers>
<DataTrigger Binding="{Binding GpoModule, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ModuleIndicator}}}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="In">
<Storyboard>
<StaticResource ResourceKey="SbFadeIn" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="In" />
</DataTrigger.ExitActions>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding GpoAnimationLocked, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ModuleIndicator}}}"
Value="False" />
<Condition Binding="{Binding GpoModule, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ModuleIndicator}}}"
Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="Out">
<StaticResource ResourceKey="SbFadeOut" />
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="Out" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Viewbox.Style>
</Viewbox>