在WPF中實現輪播圖的方法有很多,本例將採用UserControl用戶自定義控件的方式進行封裝,以下是具體實現步驟:
1.新建WPF項目,新建一個UserControl用戶自定義控件用來作爲我們的輪播圖控件(本例:PrintS/UC/RollImg.xaml):
xaml:
<UserControl x:Class="PrintS.UC.RollImg"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="900" d:DesignWidth="900">
<Grid>
<Canvas Name="canvas_board" ClipToBounds="True"
Height="900" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="900">
<Image Name="image1"
Canvas.Left="0" Canvas.Top="0" Height="900" Stretch="Fill" Width="900" />
<Image Name="image2"
Canvas.Left="0" Canvas.Top="0" Height="900" Stretch="Fill" Width="900" />
</Canvas>
</Grid>
</UserControl>
使用一個canvas,兩個image用來繪製輪播圖動畫
xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
namespace PrintS.UC
{
/// <summary>
/// RollImg.xaml 的交互邏輯
/// </summary>
public partial class RollImg : UserControl
{
public RollImg()
{
InitializeComponent();
}
/// <summary>
/// 是否開始滾動
/// </summary>
public bool isBegin = false;
/// <summary>
/// 本輪剩餘滾動數
/// </summary>
public int rollNum = 0;
private List<BitmapImage> _ls_images;
/// <summary>
/// 滾動圖片組
/// </summary>
public List<BitmapImage> ls_images
{
set
{
if (rollNum > 0)
{
// 本輪滾動未結束
}
else
{
// 開始新的一輪滾動
_ls_images = value;
rollNum = _ls_images.Count();
}
}
get { return _ls_images; }
}
/// <summary>
/// 滾動寬度
/// </summary>
public double width
{
get { return this.canvas_board.Width; }
}
/// <summary>
/// 滾動高度
/// </summary>
public double height
{
get { return this.canvas_board.Height; }
}
private int n_index = 0; // 滾動索引
private Storyboard _storyboard_R2L;
/// <summary>
/// 滾動動畫板
/// </summary>
public Storyboard storyboard_R2L
{
get
{
if (_storyboard_R2L == null)
{
_storyboard_R2L = new Storyboard();
DoubleAnimationUsingKeyFrames daukf_img1 = new DoubleAnimationUsingKeyFrames();
LinearDoubleKeyFrame k1_img1 = new LinearDoubleKeyFrame(0.0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(5)));
LinearDoubleKeyFrame k2_img1 = new LinearDoubleKeyFrame(-this.width, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(8)));
daukf_img1.KeyFrames.Add(k1_img1);
daukf_img1.KeyFrames.Add(k2_img1);
_storyboard_R2L.Children.Add(daukf_img1);
Storyboard.SetTarget(daukf_img1, this.image1);
Storyboard.SetTargetProperty(daukf_img1, new PropertyPath("(Canvas.Left)"));
DoubleAnimationUsingKeyFrames daukf_img2 = new DoubleAnimationUsingKeyFrames();
LinearDoubleKeyFrame k1_img2 = new LinearDoubleKeyFrame(this.width, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(5)));
LinearDoubleKeyFrame k2_img2 = new LinearDoubleKeyFrame(0.0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(8)));
daukf_img2.KeyFrames.Add(k1_img2);
daukf_img2.KeyFrames.Add(k2_img2);
_storyboard_R2L.Children.Add(daukf_img2);
Storyboard.SetTarget(daukf_img2, this.image2);
Storyboard.SetTargetProperty(daukf_img2, new PropertyPath("(Canvas.Left)"));
_storyboard_R2L.FillBehavior = FillBehavior.Stop;
_storyboard_R2L.Completed += new EventHandler(storyboard_Completed);
}
return _storyboard_R2L;
}
}
void storyboard_Completed(object sender, EventArgs e)
{
rollNum--;
// 顯示圖片
this.ResetStory();
// 繼續下輪動畫
storyboard_R2L.Begin();
}
/// <summary>
/// 開始滾動動畫
/// </summary>
public void Begin()
{
if (!isBegin)
{
isBegin = true;
// 顯示圖片
this.ResetStory();
// 開始動畫
storyboard_R2L.Begin();
}
}
/// <summary>
/// 初始化動畫版,顯示動畫中的圖片
/// </summary>
void ResetStory()
{
// 復位
this.image1.SetValue(Canvas.LeftProperty, 0.0);
this.image2.SetValue(Canvas.LeftProperty, this.width);
// 顯示圖片
if (this.ls_images.Count > 0)
{
try
{
this.image1.Source = this.ls_images[this.n_index++ % this.ls_images.Count];
this.image2.Source = this.ls_images[this.n_index % this.ls_images.Count];
}
catch (Exception ex)
{
this.image1.Source = new BitmapImage();
this.image2.Source = new BitmapImage();
}
}
else
{
this.image1.Source = new BitmapImage();
this.image2.Source = new BitmapImage();
}
}
}
}
2.在主窗口中,引用自定義控件:
MainWindow.xaml:
<Window x:Class="PrintS.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:PrintS.UC"
Title="PrintS" Height="900" Width="1440"
WindowState="Maximized" WindowStyle="None">
<Grid Background="#e2efe1">
<uc:RollImg x:Name="rollImg"
Height="900" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="900" />
</Grid>
</Window>
需要添加自定義控件所在的命名空間:xmlns:uc="clr-namespace:PrintS.UC"
使用時:<uc:RollImg .... />
MainWindow.xaml.cs:
List<BitmapImage> ls_adv_img = new List<BitmapImage>();
// 根據自己的業務邏輯進行賦值操作
foreach (Adv a in listAdv)
{
BitmapImage img;
try
{
img = new BitmapImage(new Uri(string.Format(@"{0}\{1}", pathAdv, a.pic)));
}
catch (Exception ex)
{
img = new BitmapImage();
}
ls_adv_img.Add(img);
}
this.rollImg.ls_images = ls_adv_img;
this.rollImg.Begin();