zoukankan      html  css  js  c++  java
  • WPF 循环切换图片达到动画效果

      最近刚接触WPF,  一边学着一边用着,知识点还没有系统化的进行学习整理.

      现在手上有一些美术做好的图片,需要连起来观看形成动画的效果,由于需求比较急,一时半会也静不下心来看WPF关于动画的知识.

      潜意识里一个Image控件,循环设定Source属性,一看效果总是显示集合的最后一项.难道是循环速度太快?基于此思路下折腾了好久也无结果。开始不得不借着可以找到的资源进行尝试。试想我们一张张的图片进行播放形成的动画,是不是类似帧的这种概念.顺这个便找到了CompositionTarget.Rendering事件创建基于帧的动画.

      第一种尝试:

    namespace ImgAniDemo
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            ObservableCollection<BitmapImage> bmList;
    
            public MainWindow()
            {
                InitializeComponent();
    
                InitList();
    
                CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
            }
    
            public void InitList()
            {
                bmList = new ObservableCollection<BitmapImage>();
                for (int i = 1; i < 4; i++)
                {
                    BitmapImage bmImg = new BitmapImage(new Uri(System.Environment.CurrentDirectory + "\\" + i.ToString() + ".jpg"));
                    bmList.Add(bmImg);
                }
            }
    
            void CompositionTarget_Rendering(object sender, EventArgs e)
            {
                for (int i = 0; i < bmList.Count; i++)
                {
                    this.imgViewer.Source = bmList[i];
                    this.imgViewer.Width = this.imgViewer.Source.Width;
                    this.imgViewer.Height = this.imgViewer.Source.Height;
                }
            }
        }
    }
    

     运行程序ImgAniDemo.exe结果还是只显示了最后一幅图片.

      回头认真思考一下,可以做一个这样的猜测,WPF是不是做了优化,如果循环去设置Image的Source属性,用户看到的效果只会是最后一张图片呢?

      Render是什么意思?不错,Rendering事件被处理的时候,我们是用了一个循环,按着上面的猜测,只会显示最后一张图片便在情理之中了.

      聪明的你一定是想到了方法,我们在Rendering事件的时候不去循环了,只指定某一个图片给Source属性不就ok了吗?

      修改后的代码:

    namespace ImgAniDemo
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
    ObservableCollection<BitmapImage> bmList;

    int index = 0; //记录索引

    public MainWindow()
    {
    InitializeComponent();

    InitList();

    CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
    }

    public void InitList()
    {
    bmList = new ObservableCollection<BitmapImage>();
    for (int i = 1; i < 4; i++)
    {
    BitmapImage bmImg = new BitmapImage(new Uri(System.Environment.CurrentDirectory + "\\" + i.ToString() + ".jpg"));
    bmList.Add(bmImg);
    }
    }

    void CompositionTarget_Rendering(object sender, EventArgs e)
    {
    if (index < bmList.Count)
    {
    this.imgViewer.Source = bmList[index];
    this.imgViewer.Width = this.imgViewer.Source.Width;
    this.imgViewer.Height = this.imgViewer.Source.Height;

    index++;
    }
    else
    {
    index = 0;
    }
    }
    }
    }

    这时候我们已经可以看到图片在自动切换了.会不会感觉速度太快了,我想按着一定的速度来控件切换怎么办?

    直接上代码了

    namespace ImgAniDemo
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
    ObservableCollection<BitmapImage> bmList;

    int index = 0; //记录索引
    bool isRendering = false;

    public MainWindow()
    {
    InitializeComponent();

    InitList();

    CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerAsync();
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
    while (true)
    {
    isRendering = true;
    System.Threading.Thread.Sleep(1000); //停1秒
    }
    }

    public void InitList()
    {
    bmList = new ObservableCollection<BitmapImage>();
    for (int i = 1; i < 4; i++)
    {
    BitmapImage bmImg = new BitmapImage(new Uri(System.Environment.CurrentDirectory + "\\" + i.ToString() + ".jpg"));
    bmList.Add(bmImg);
    }
    }

    void CompositionTarget_Rendering(object sender, EventArgs e)
    {
    if (isRendering)
    {
    if (index < bmList.Count)
    {
    this.imgViewer.Source = bmList[index];
    this.imgViewer.Width = this.imgViewer.Source.Width;
    this.imgViewer.Height = this.imgViewer.Source.Height;

    index++;
    }
    else
    {
    index = 0;
    }
    isRendering = false;
    }
    }
    }
    }

    在运行看下效果呢?

    呵呵,图片是不是在自动播放呢?

    注:以上代码中用到的图片名称分别为1.jpg,2.jpg,3.jpg,且图片放在exe程序一起即可

    以上仅是个人想到的一种方法,若有不正确的地方,还请多多指点...

  • 相关阅读:
    网页版台球小游戏
    代码写响应式时钟效果
    如何使用SVN?
    TP框架---View视图层---模板继承(举例说明)
    ThinkPhp框架:文件上传
    ThinkPhp框架:验证码功能
    ThinkPhp框架:父类及表单验证
    ThinkPhp框架对“数据库”的基本操作
    对thinkphp的命名空间的理解
    控制器操作方法的调用
  • 原文地址:https://www.cnblogs.com/dreamzgj/p/2373850.html
Copyright © 2011-2022 走看看