65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF 驱动的不规则弹出窗口演示

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (17投票s)

2008年6月17日

CPOL

4分钟阅读

viewsIcon

86282

downloadIcon

3231

本文介绍了如何使用 WPF 创建一个渐入渐出不规则弹出窗口。

Pop up window demo

引言

在屏幕右下角出现一个小弹出窗口显示一些信息,就像 Live Messenger 所做的那样,对用户来说更友好,不是吗?在 .NET 2.0 中,我们可以使用 Form.Opacity 属性用几行代码创建一个渐入渐出窗口,但创建不规则窗口要困难得多。现在我们有了 .NET 3.5 中的 WPF,使用它,您只需更改一些窗口属性即可创建不规则窗口,并且还可以获得更流畅的渐入渐出动画体验。

背景

这是我的第一个 WPF 程序,仅供娱乐。我希望大家都会对此感兴趣。

如何使用 XAML 创建渐入渐出窗口

首先,我们需要创建一个窗口 :),并在其中添加您想要的内容,文本框、组合框等。然后我们需要创建一个 Storyboard,它是一个容器时间线,以及一个 DoubleAnimation,它使用线性插值在指定的 Duration 上动画化 Double 属性的值,对于这个窗口,如下所示:

    <BeginStoryboard>
        <Storyboard Name="FormFade">
            <DoubleAnimation  Name="FormFadeAnimation"
                Storyboard.TargetName="winMain" 
                Storyboard.TargetProperty="(Window.Opacity)"
                From="0.0" To="1.0" Duration="0:0:2" 
                AutoReverse="False" RepeatBehavior="1x" 
            />
         </Storyboard>
    </BeginStoryboard>

这里是对以上 XAML 的一些解释,您可以通过搜索 MSDN 来获取关于每个关键字的更详细信息。

  • TargetName:设置要动画化的对象的名称。这里我的窗口名为“winMain”,所以将它赋给此属性。
  • TargetProperty:设置应该被动画化的属性。我们想创建一个渐入渐出窗口,所以只需不断更改其不透明度属性。
  • From, To:动画的开始值和结束值。这里表示不透明度将从 0.0 更改为 1.0。
  • Duration:设置此时间线的播放时长,不包括重复。换句话说,此动画每次将播放 2 秒。
  • AutoReverse:设置一个值,指示时间线在完成一次正向迭代后是否反向播放。如果为False,则它只进行渐入,因为动画 XAML 只指示它这样做。如果设置为True,则在渐入之后,它将进行反向动画,是的,它将渐出。
  • RepeatBehavior:设置此时间线的重复行为。这里我们希望它只播放一次。您可以将其更改为Forever,它指定时间线将无限重复。
  • 最后,我们需要将此动画附加到窗口的 Loaded 事件,我们需要添加一个事件触发器,所以最终的 XAML 如下所示:

        <Window.Triggers>
            <EventTrigger RoutedEvent="Window.Loaded">
                <BeginStoryboard>
                    <Storyboard Name="FormFade">
                        <DoubleAnimation  Name="FormFadeAnimation"
                                                Storyboard.TargetName="winMain" 
                                                Storyboard.TargetProperty="(Window.Opacity)"
                                                From="0.0" To="1.0" Duration="0:0:2" 
                                                AutoReverse="False" RepeatBehavior="1x" 
                                             />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Window.Triggers>
    

    现在我们有了一个仅通过编写 XAML 就具有渐入动画的主窗口,完全没有 C# 代码。

    demo window

    如何使用代码创建渐入渐出不规则窗口

    对于上面的渐入渐出窗口(上面的窗口只有渐入动画,您可以将AutoReverse更改为True以获得渐出动画),我们也可以使用 C# 代码来实现。这是本节的重点。

    我们希望窗口在 1.5 秒内渐入,显示一些文本,然后用另外 1.5 秒渐出。当然,这个窗口是不规则的,并显示在屏幕的右下角。

    首先,我们需要创建一个 Window 对象实例。

        //Create a Window
        Window popUp = new Window();
        popUp.Name = "PopUp";
        
        //The following properties are used to create a irregular window
        popUp.AllowsTransparency = true;
        popUp.Background = Brushes.Transparent;
        popUp.WindowStyle = WindowStyle.None;
        
        popUp.ShowInTaskbar = false;
        popUp.Topmost = true;
        popUp.Height = winHeight;
        popUp.Width = winWidth;
        //Set postion to right lower corner of the screen
        popUp.Left = Screen.PrimaryScreen.Bounds.Width - winWidth;        
        popUp.Top = Screen.PrimaryScreen.Bounds.Height - winHeight - 30;
    

    为了创建不规则窗口,我们需要设置三个属性:

  • AllowsTransparency:设置为True
  • WindowStyle:设置为WindowStyle.None
  • Background:设置为Brushes.Transparent
  • 然后我们创建一个 Grid 作为容器,一个 Image 来显示一个不规则的背景图像作为窗口边框,以及一个 TextBlock 用于显示消息。

        //Create a inner Grid
        Grid g = new Grid();
    
        //Create a Image for irregular background display
        Image img = new Image();
        img.Stretch = Stretch.Fill;
        img.Source = bgImg;
        img.BitmapEffect = new System.Windows.Media.Effects.DropShadowBitmapEffect();
        g.Children.Add(img);
    
        //Create a TextBlock for message display
        TextBlock msg = new TextBlock();
        msg.Padding = msgPadding;
        msg.VerticalAlignment = VerticalAlignment.Center;
        msg.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
        msg.TextWrapping = TextWrapping.Wrap;
        msg.Text = msgText;
        g.Children.Add(msg);
    
        popUp.Content = g;
    

    现在我们有了窗口,下一步是为这个窗口添加渐入渐出动画。

    对于动画,我们在创建 Storyboard(上面提到的容器时间线)之前必须创建一个 NameScope。我们创建一个 DoubleAnimation,就像上面的 XAML 一样。需要提的一点是,为了在窗口渐出时关闭它,将一个委托函数附加到 DoubleAnimation.Complete 事件,以调用 Window.Close() 方法。

    然后我们将此动画添加到 Storyboard,并向 Window.Loaded 事件添加另一个委托函数,以便在 Window 加载时播放此动画。最后,我们调用 Window.Show() 方法显示窗口,我们就可以看到动画自动开始播放了。

        //Register the window's name, this is necessary for creating Storyboard using codes instead of XAML
        NameScope.SetNameScope(popUp, new NameScope());
        popUp.RegisterName(popUp.Name, popUp);
    
        //Create the fade in & fade out animation
        DoubleAnimation winFadeAni = new DoubleAnimation();
        winFadeAni.From = 0;
        winFadeAni.To = 1;
        winFadeAni.Duration = new Duration(TimeSpan.FromSeconds(1.5));        //Duration for 1.5 seconds
        winFadeAni.AutoReverse = true;
        winFadeAni.Completed += delegate(object sender, EventArgs e)            //Close the window when this animation is completed
        {
            popUp.Close();
        };
    
        // Configure the animation to target the window's opacity property
        Storyboard.SetTargetName(winFadeAni, popUp.Name);
        Storyboard.SetTargetProperty(winFadeAni, new PropertyPath(Window.OpacityProperty));
    
        // Add the fade in & fade out animation to the Storyboard
        Storyboard winFadeStoryBoard = new Storyboard();            
        winFadeStoryBoard.Children.Add(winFadeAni);
    
        // Set event trigger, make this animation played on window.Loaded
        popUp.Loaded += delegate(object sender, RoutedEventArgs e)
        {
            winFadeStoryBoard.Begin(popUp);
        };
    
        //Finally show the window
        popUp.Show();
    

    这是最终的弹出窗口,玩得开心。

    pop up window

    关注点

    有了 WPF,我们可以用更少的代码创建漂亮的 UI,我们可以播放窗口动画,并且可以让动画更流畅。WPF 带来了许多新功能和出色的 UI 体验,这些才是真正值得关注的。在使用 WPF 方面有什么新想法吗?

    历史

    2008.6.17, 版本 1.0.0

    © . All rights reserved.