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

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

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

[编辑]

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

【问题讨论】:

    标签: wpf animation visibility


    【解决方案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很慢,所以如果你需要滑动动画:

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

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

    3. 将此面板的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 时它会立即消失,而不是不透明度发生变化然后消失
    • 这很可能发生,因为在动画运行之前我们被设置为不可见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 2021-07-27
    • 2014-10-17
    • 2013-11-28
    • 1970-01-01
    • 2014-04-07
    相关资源
    最近更新 更多