WPF动画窗口可见性变化

7

我正在尝试弄清楚如何为WPF窗口动画更改从Visible到Hidden的过程。我当前的应用程序工作方式是窗口通常处于隐藏状态,当我将鼠标移到屏幕侧面时它会弹出,我正在使用布尔值可见性转换器来实现这一点,但是我希望在鼠标悬停时更平滑地滑出应用程序,并在此之后再次滑回。

我还没有尝试过任何动画效果,所以我不确定该如何做。首先,我不确定应该使用什么动画来完成这个过程,其次,我不确定是否应该在视图模型中触发“IsWindowVisible”属性或者是否应该将其绑定到VisibilityChanged事件,第三,我不确定当窗口大小可变时是否可行。

[编辑]

如果必要,我可以采用透明度解决方案,但这并不完全符合我试图达到的“滑动”效果。

2个回答

16
我做了类似这样的事情(透明度在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 在移动窗口时会变慢:
1. 制作一个透明窗口(AllowsTransparency="True" Background="Transparent" WindowStyle="None") 2. 将所有控件放入不透明面板中(Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}") 3. 动画该面板的Margin.Left0到窗口的ActualWidth,然后隐藏窗口 - 这将解决保存窗口大小的问题。

这基本上是可行的。我的窗口已经是透明的,所以我直接将它绑定到Window.Left属性。我还在代码后端实现,而不是XAML中,因为我需要窗口的宽度依赖于其他因素。 - John
我想在 DockPanel 面板中使用这段代码,但是我无法将 Storyboard 放入 xmal 文件中,我该怎么办? - icaptan
@icaptan 你需要在代码中创建一个故事板,例如 var sb = new Storyboard(); sb.Children.Add(opacityAnimation); sb.Children.Add(visibilityAnimation); sb.Begin(this) - Mykola Bohdiuk
@PraneshJanarthanan,你在<DoubleAnimation ...>中把0.75改成了1.0吗? - Mykola Bohdiuk
@PraneshJanarthanan 好的,我的问题就是答案。<DoubleAnimation ...> 允许您指定动画属性,如动画属性 TargetPropertyDuration 和最终属性值 To - Mykola Bohdiuk
显示剩余5条评论

3

使用Windows的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

问题在于,要使此属性为True,您需要将WindowStyle设置为None。这意味着您的窗口周围没有框架。这意味着没有关闭、最小化、最大化、还原、标题栏。

您必须提供一个自定义模板(可能继承Window类),以放置这些按钮。


3
我尝试使用你的解决方案,但当IsVisible == true时它正确地淡入,但当IsVisible == false时,它立刻消失而不是改变透明度然后消失。 - John
这很可能是因为在动画运行之前,我们被设置为不可见。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接