C# WPF 在可见性触发器中对不透明度进行动画处理



我正在创建一个包含动画的样式,然后可以将其继承为自动应用的特定控件样式。

实际上,我正在努力实现一个简单的动画:

  • Visibility更改为 Visible 时,Opacity 从 0 更改为 1
  • Visibility更改为visible以外的其他东西时,Opacity正在做相反的事情

到目前为止,我得到了:

<Style x:Key="BaseAnimationsStyle">
    <Style.Triggers>
        <Trigger Property="FrameworkElement.Visibility" Value="Visible">
            <Trigger.EnterActions> <!-- this works -->
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.5" />
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions><!-- this doesn't -->
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.5" />
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>

如果在控件上设置了上述样式,则它具有以下行为:

当控件的Visibility设置为Visible时,过渡工作正常,这意味着它正在淡入。

问题:当控件的Visibility设置为 Hidden(甚至Collapsed(时,控件将立即隐藏而不会褪色。

我的猜测是,在FrameworkElement处理可见性更改的方式中,有一些默认行为需要覆盖。

Visibility 属性设置为 CollapsedHidden 将使元素立即不可见,但您可以设置您的一些附加属性,然后对 Opacity 属性进行动画处理以淡出元素,而不是设置 Visibility 属性。请参阅以下链接以获取更多信息和示例。

WPF:如何对可见性属性进行动画处理?:

http://blogs.microsoft.co.il/arik/2010/02/08/wpf-how-to-animate-visibility-property/ https://www.codeproject.com/Articles/57175/WPF-How-To-Animate-Visibility-Property

WPF 淡入淡出动画

我已经用@mm8的答案提供的信息解决了我的问题。

基本上,我将可见性动画类添加到我的项目中。然后,我只是使用在 Setter 中提供的附加属性创建了我的基本样式。

<!-- Animations -->
<Style x:Key="BaseAnimationsStyle">
    <Setter Property="anim:VisibilityAnimation.AnimationType" Value="Fade" />
</Style>

<!-- This adds the Visibility Animation to every Grid which has access to this resource -->
<Style TargetType="{x:Type Grid}" BasedOn="{StaticResource BaseAnimationsStyle}" />

另一种解决方案:

为可见性创建附加属性。这使您能够设置任何控件的可见性,而无需自动设置不透明度。

如果要对属性使用 Bindings,则绑定的第一次计算会导致动画(如果值未Visibility.Visible 。这就是为什么需要另一个属性来指定另一个可见性来启动的原因。

public static class AnimateableVisibility
{
    public static readonly DependencyProperty VisibilityProperty = DependencyProperty.RegisterAttached(
        "Visibility", typeof(Visibility), typeof(AnimateableVisibility), new PropertyMetadata(default(Visibility), VisibilityPropertyChanged));
    private static void VisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var val = (Visibility) e.NewValue;
        // Set StartVisibility to Visible when Visibility is set to Visible
        if (val == Visibility.Visible) 
            d.SetCurrentValue(StartVisibilityProperty, val);
    }

    public static readonly DependencyProperty StartVisibilityProperty = DependencyProperty.RegisterAttached(
        "StartVisibility", typeof(Visibility), typeof(AnimateableVisibility), new PropertyMetadata(default(Visibility)));
    public static Visibility GetVisibility(DependencyObject obj)
    {
        return (Visibility)obj.GetValue(VisibilityProperty);
    }
    public static void SetVisibility(DependencyObject obj, Visibility value)
    {
        obj.SetValue(VisibilityProperty, value);
    }

    public static Visibility GetStartVisibility(DependencyObject obj)
    {
        return (Visibility)obj.GetValue(VisibilityProperty);
    }
    public static void SetStartVisibility(DependencyObject obj, Visibility value)
    {
        obj.SetValue(VisibilityProperty, value);
    }
}

现在,您可以按如下方式使用这些属性:

<Grid>
    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal">
        <Button Margin="5,0,15,0" Padding="7,0" Style="{StaticResource VisibilityAnimation}" utils:AnimateableVisibility.StartVisibility="Hidden"
            utils:AnimateableVisibility.Visibility="{Binding ElementName=CheckBox, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}">I'm a Button</Button>
        <CheckBox VerticalAlignment="Center" IsChecked="False" x:Name="CheckBox"></CheckBox>
    </StackPanel>
</Grid>

通过将StartVisibility更改为 Visible ,您可以看到Button在启动时如何淡出。

现在缺少的只是应用的样式:

<Style x:Key="VisibilityAnimation">
    <Style.Triggers>
        <Trigger Property="utils:AnimateableVisibility.StartVisibility" Value="Hidden">
            <!-- This avoids the Animation in cases when the first evaluation of AnimateableVisibility.Visibility is false -->
            <Setter Property="UIElement.Visibility" Value="Hidden" />
        </Trigger>
        <Trigger Property="utils:AnimateableVisibility.Visibility" Value="Visible">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard TargetProperty="Opacity">
                        <DoubleAnimation To="1" Duration="0:0:2"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard>
                    <Storyboard TargetProperty="Opacity">
                        <DoubleAnimation To="0" Duration="0:0:2"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>

相关内容

  • 没有找到相关文章

最新更新