WPF 动画窗口可见性更改

Posted

技术标签:

【中文标题】WPF 动画窗口可见性更改【英文标题】:WPF Animate Window Visibility Change 【发布时间】:2011-05-28 22:55:53 【问题描述】:

我试图弄清楚如何为 WPF 窗口从 Visibile 更改为 Hidden 的动画。我目前让应用程序工作的方式是窗口通常是隐藏的,当我将鼠标移动到屏幕的一侧时它会弹出,我正在使用布尔到可见性转换器来做到这一点,但我想做什么是让应用程序在鼠标悬停时更顺畅地滑出,然后再次滑入。

我没有做任何动画,所以我不知道该怎么做。首先,我不确定我应该使用什么动画来执行此操作,其次我不确定是否应该在视图模型中的“IsWindowVisibile”属性上触发它,或者是否应该将其绑定到 VisibilityChanged 事件,第三我'不确定当窗口大小可变时这是否可能。

[编辑]

如有必要,我将“采用”不透明解决方案,但这并不是我想要获得的“滑动”效果。

【问题讨论】:

【参考方案1】:

我做了类似的事情(不透明度在 2 秒内变为 0,窗口隐藏):看看代码,很简单

MainWindow.xaml:

    <Storyboard x:Key="hideMe">
        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" To="0.0"/>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0:0:2" Value="x:Static Visibility.Hidden"/>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="showMe">
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="x:Static Visibility.Visible"/>
        </ObjectAnimationUsingKeyFrames>
        <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:5" To="0.75"/>
    </Storyboard>

MainWindow.xaml.cs

    public void ShowMe() 
        (FindResource("showMe") as Storyboard).Begin(this);
    
    public void HideMe() 
        (FindResource("hideMe") as Storyboard).Begin(this);
    

只需调用HideMe()ShowMe() 而不是在代码中设置Visibility = Visibility.Hidden

编辑

移动窗口时WPF很慢,所以如果你需要滑动动画:

    制作透明窗口 (AllowsTransparency="True" Background="Transparent" WindowStyle="None")

    将所有控件放在不透明面板上 (Background="StaticResource x:Static SystemColors.ControlBrushKey")

    将此面板的Margin.Left0 动画到窗口的ActualWidth,然后隐藏一个窗口 - 这将解决保存窗口大小的问题

【讨论】:

这很有效。我的窗口已经是透明的,所以我只是将它直接绑定到 Window.Left 属性。我也在代码后面而不是 XAML 中这样做,因为我需要窗口宽度来依赖于视图的不同因素 我想将此代码用于 DockPanel 面板,但我无法将 Storyboard 放入 xmal 文件中,我该怎么做? @icaptan 您需要在代码中创建故事板,例如var sb = new Storyboard(); sb.Children.Add(opacityAnimation); sb.Children.Add(visibilityAnimation); sb.Begin(this) 但是为什么不像你的例子那样在 xaml 文件中呢?我很快就试试!谢谢 @icaptan 在之前的评论中你说你不能把它放到xaml中,所以我提出了非xaml的方式【参考方案2】:

使用 Window 的 Opacity/Visibility 需要一个简单的 DoubleAnimation

示例:

IsVisibleChanged += new DependencyPropertyChangedEventHandler(MainWindow_IsVisibleChanged);

void MainWindow_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)

    DoubleAnimation da = new DoubleAnimation()
    
        From = (IsVisible) ? 0 : 1,
        To = (IsVisible) ? 1 : 0,
        Duration = TimeSpan.FromSeconds(1)
    ;

    BeginAnimation(Window.OpacityProperty, da);

问题:

要使其按预期工作,您需要在窗口上将 AllowsTransparency 设置为 True。如果你不设置这个,你的Opacity 设置为0 的窗口将是Black

问题是此属性为True,您需要将WindowStyle 设置为None。这意味着您的窗户周围没有框架。这意味着没有关闭、最小化、最大化、恢复、标题栏。

您必须提供一个自定义模板(可能继承Window 类)才能将这些按钮放在那里。

【讨论】:

我正在尝试使用您的解决方案,但是当 IsVisible == true 时它会正确淡入,当 IsVisibile == false 时它会立即消失,而不是不透明度发生变化然后消失 这很可能发生,因为在动画运行之前我们被设置为不可见。

以上是关于WPF 动画窗口可见性更改的主要内容,如果未能解决你的问题,请参考以下文章

WPF:尝试根据组合框中的选择更改可见性

WPF XAML 网格可见性触发器

WPF 在编辑时设置默认可见性值

markdown 根据序列步骤更改窗口小部件可见性

markdown 根据序列步骤更改窗口小部件可见性

markdown 根据序列步骤更改窗口小部件可见性