WPF 渐隐渐现切换背景图片

最近学习WPF,尝试着自己做一些小玩意,也遇到了一些问题,于是整理记录以便日后查阅。

我们都知道WPF可以实现一些很炫的效果,然而有时候为达到这个目的却并不是一件很容易的事情。比如:在软件中我希望能够通过渐隐渐现实现窗体背景的切换,在网上也没找到相关的Demo,只好硬着头皮去看相关的API。

要实现渐隐渐现的效果并不难,只需要通过控制修改背景的透明度即可实现,然而,如何在渐隐之后切换另一个图片背景再渐现出来却着实难了我很久。所幸终于找到了一个解决方案。相关实现过程如下:

  <Border x:Name="bgBorder" CornerRadius="3,3,3,3">
        <Border.Background>
            <ImageBrush ImageSource="Image/bg.jpg" Stretch="UniformToFill"/>
        </Border.Background>
    ...
  </Border>

这里我使用的是自定义窗体,如上所示,我们需要对Border的背景图片进行替换。

首先是定义一段渐隐的动画,通过修改背景的透明度即可:

   1:  DoubleAnimationUsingKeyFrames da = new DoubleAnimationUsingKeyFrames();
   2:   EasingDoubleKeyFrame sd = new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(1005)));
   3:   da.KeyFrames.Add(sd);
   4:   Storyboard.SetTargetName(da, bgBorder.Name);
   5:   DependencyProperty[] propertyChain = new DependencyProperty[]
   6:  {
   7:         Panel.BackgroundProperty,
   8:         Brush.OpacityProperty
   9:  };
  10:  Storyboard.SetTargetProperty(da, new PropertyPath("(0).(1)", propertyChain));

 

然后定义一段渐现的动画,也是通过修改透明度进行:

   1:  DoubleAnimationUsingKeyFrames da2 = new DoubleAnimationUsingKeyFrames();
   2:  da2.BeginTime = new TimeSpan(0, 0, 0, 1, 5);
   3:  EasingDoubleKeyFrame sd2 = new EasingDoubleKeyFrame(1, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(1200)));
   4:  da2.KeyFrames.Add(sd2);
   5:  Storyboard.SetTargetName(da2, bgBorder.Name);
   6:  Storyboard.SetTargetProperty(da2, new PropertyPath("(0).(1)", propertyChain));

 

最后是在两段动画之间插入一个修改背景图片的小动画:

   1:  ObjectAnimationUsingKeyFrames oa = new ObjectAnimationUsingKeyFrames();
   2:  DiscreteObjectKeyFrame diso = new DiscreteObjectKeyFrame(new BitmapImage(new Uri(@"/Test;component/Image/bg.jpg", UriKind.Relative)), KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(10)));
   3:   oa.KeyFrames.Add(diso);
   4:   oa.BeginTime = new TimeSpan(0, 0, 0, 1, 0);
   5:   Storyboard.SetTargetName(oa, bgBorder.Name);
   6:  DependencyProperty[] propertyChain2 = new DependencyProperty[]
   7:  {
   8:         Panel.BackgroundProperty,
   9:         ImageBrush.ImageSourceProperty
  10:  };
  11:  Storyboard.SetTargetProperty(oa, new PropertyPath("(0).(1)", propertyChain2));

 

接着将三段动画组合起来:

   1:  bgstoryboard.Children.Add(da);
   2:  bgstoryboard.Children.Add(oa);
   3:  bgstoryboard.Children.Add(da2);

 

但是现在只是做到了背景的渐隐渐现还是无法做到背景切换,如下功能就是实现背景切换:

   1:  private void BgSwitch(string imgPath)
   2:  {
   3:        var obj = bgstoryboard.Children.FirstOrDefault(c => c is ObjectAnimationUsingKeyFrames);
   4:        if (obj != null)
   5:        {
   6:              ObjectAnimationUsingKeyFrames oa = obj as ObjectAnimationUsingKeyFrames;
   7:              if (oa.KeyFrames.Count > 0)
   8:              {
   9:                  oa.KeyFrames[0].Value = new BitmapImage(new Uri(imgPath));
  10:              }
  11:        }
  12:  }

 

想要实现每隔一段时间更换一次背景,我们还需要一个Timer来控制:

   1:  bgTimer = new DispatcherTimer();
   2:  bgTimer.Interval = new TimeSpan(0, 0,5);
   3:  bgTimer.Tick += bgTimer_Tick;

为了看到效果,将Timer间隔设置为五秒

 

   1:          void bgTimer_Tick(object sender, EventArgs e)
   2:          {
   3:              if (ListImages.Count > 0)
   4:              {
   5:                  if (ImageIndex >= ListImages.Count)
   6:                  {
   7:                      ImageIndex = 0;
   8:                  }
   9:                  BgSwitch(ListImages[ImageIndex]);
  10:                  if (ImageIndex == 1 && ListImages.Count == 1)
  11:                  {
  12:                      bgTimer.Stop();
  13:                  }
  14:                  else
  15:                  {
  16:                      bgstoryboard.Begin(this);
  17:                      ImageIndex++;
  18:                  }
  19:                  
  20:              }
  21:              
  22:          }

ListImages是要替换的背景图片路径集合,如果只有一张背景图片,我们是不需要启动替换动画的。

最后的效果如下:

image

隔五秒之后,替换成另外一个背景:

image

 

Demo下载地址:Demo

posted @ 2014-04-10 09:50  月影银沙  阅读(1821)  评论(0编辑  收藏  举报