最近剛接觸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程序一起即可
以上僅是個人想到的一種方法,若有不正確的地方,還請多多指點...