經(jīng)常閱讀電子雜志的朋友對(duì)其流暢自然的翻頁(yè)過(guò)渡效果應(yīng)當(dāng)留下了十分深刻的印象。這些雜志都是使用Flash技術(shù)制作而成的??傁胫苡?/span>Silverlight實(shí)現(xiàn)這樣的效果,去網(wǎng)上查查資料,找到了一個(gè)微軟官方提供的翻頁(yè)效果例子(教程說(shuō)明點(diǎn)這里,在線實(shí)例演示及源代碼下載點(diǎn)這里)。
最近自己親自動(dòng)手做了個(gè)翻書的小程序,內(nèi)容大致如下:
導(dǎo)航:
①建立翻頁(yè)項(xiàng)目解決方案
②添加必要文件
③構(gòu)建應(yīng)用程序界面
④設(shè)置應(yīng)用程序控制邏輯
⑤最終效果圖
1、建立翻頁(yè)項(xiàng)目解決方案
點(diǎn)擊File->Projects...菜單選項(xiàng),新建一個(gè)ASP.NET Web Application。
將新建工程名稱命名為FlipPage。
在解決方案下繼續(xù)添加一個(gè)Silverlight應(yīng)用程序項(xiàng)目,將該工程命名為SilverlightClient。
在彈出的對(duì)話框中,直接點(diǎn)OK按鈕。
點(diǎn)擊一下“全部保存”按鈕,完成項(xiàng)目工程的創(chuàng)建。
2、添加必要文件
在SilverlightClient項(xiàng)目文件夾下,新建一個(gè)名為Dll的文件夾,在里面放入WPF and Silverlight BookControls的動(dòng)態(tài)鏈接庫(kù)文件SLMitsuControls.dll(如下圖)。在FlipPage項(xiàng)目文件夾下,新建一個(gè)名為mediaPictures的子文件夾,在里面放入將在書中顯示的圖片,如下圖所示命名。同樣的,在SilverlightClient項(xiàng)目文件夾下,新建一個(gè)名為PageType的文件夾,然后再新建兩個(gè)類分別命名為LeftPage.cs和RightPage.cs(如下圖),它們分別代表了書的偶數(shù)和奇數(shù)頁(yè)面,具體代碼如下所示(詳細(xì)的說(shuō)明請(qǐng)見代碼注釋)。
LeftPage.cs文件代碼:
Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace SilverlightClient.TypePage
{
public class LeftPage : Canvas
{
//定義將在頁(yè)面上顯示的元素
private Image imgPhoto;
private Button btnPrevious;
private Rectangle RecBorder;
private TextBlock PageNum;
//構(gòu)造函數(shù)
public LeftPage()
{
//頁(yè)面的設(shè)置
this.Width = 452;
this.Height = 630;
this.Background = new SolidColorBrush(Colors.White);
Canvas.SetLeft(this, 0);
Canvas.SetTop(this, 0);
//頁(yè)面邊框的設(shè)置
RecBorder = new Rectangle();
RecBorder.Width = 452;
RecBorder.Height = 630;
Canvas.SetLeft(RecBorder, 0);//設(shè)置頁(yè)面邊框在Canvas中的位置,下同。
Canvas.SetTop(RecBorder, 0);
RecBorder.Stroke = new SolidColorBrush(Colors.Black);
RecBorder.StrokeThickness = 0;
this.Children.Add(RecBorder);
//照片的設(shè)置
imgPhoto = new Image();
imgPhoto.Width = 450;
imgPhoto.Height = 600;
Canvas.SetLeft(imgPhoto, 1);
Canvas.SetTop(imgPhoto, 1);
this.Children.Add(imgPhoto);
//“前一頁(yè)”按鈕的設(shè)置
btnPrevious = new Button();
btnPrevious.Width = 150;
btnPrevious.Height = 20;
btnPrevious.Content = "<< 前一頁(yè)";
btnPrevious.HorizontalContentAlignment = HorizontalAlignment.Center;
btnPrevious.VerticalContentAlignment = VerticalAlignment.Center;
btnPrevious.Cursor = Cursors.Hand;
Canvas.SetLeft(btnPrevious, 151);
Canvas.SetTop(btnPrevious, 605);
this.Children.Add(btnPrevious);
//頁(yè)碼文本的設(shè)置
PageNum = new TextBlock();
PageNum.Width = 100;
PageNum.Height = 20;
PageNum.Text = "00 / 00";
PageNum.TextAlignment = TextAlignment.Left;
PageNum.VerticalAlignment = VerticalAlignment.Center;
PageNum.FontFamily = new FontFamily("Comic sans MS");
Canvas.SetLeft(PageNum, 10);
Canvas.SetTop(PageNum, 607);
this.Children.Add(PageNum);
}
//設(shè)置圖片路徑
public void setterimgPhoto(string path)
{
BitmapImage btm = new BitmapImage();
btm.UriSource = new Uri(path, UriKind.Relative);
imgPhoto.Source = btm;
}
//設(shè)置按鈕是否可見
public void setterDisplayBtnPrevious(bool YesNo)
{
if (YesNo)
{
btnPrevious.Visibility = Visibility.Visible;
}
else {
btnPrevious.Visibility = Visibility.Collapsed;
}
}
//設(shè)置頁(yè)碼
public void setterPageNumber(string currentPageNum, string TotalPageNum) {
PageNum.Text = currentPageNum + " / " + TotalPageNum;
}
//返回按鈕單擊事件關(guān)聯(lián)
public Button getbtnPrevious()
{
return btnPrevious;
}
}
}
RightPage.cs文件代碼:
Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace SilverlightClient.TypePage
{
public class RightPage : Canvas
{
//定義將在頁(yè)面上顯示的元素
private Image imgPhoto;
private Button btnNext;
private Rectangle RecBorder;
private TextBlock PageNum;
//構(gòu)造函數(shù)
public RightPage()
{
//頁(yè)面的設(shè)置
this.Width = 452;
this.Height = 630;
this.Background = new SolidColorBrush(Colors.White);
Canvas.SetLeft(this, 0);//設(shè)置頁(yè)面邊框在Canvas中的位置,下同。
Canvas.SetTop(this, 0);
//頁(yè)面邊框的設(shè)置
RecBorder = new Rectangle();
RecBorder.Width = 452;
RecBorder.Height = 630;
Canvas.SetLeft(RecBorder, 0);
Canvas.SetTop(RecBorder, 0);
RecBorder.Stroke = new SolidColorBrush(Colors.Black);
RecBorder.StrokeThickness = 0;
this.Children.Add(RecBorder);
//照片的設(shè)置
imgPhoto = new Image();
imgPhoto.Width = 450;
imgPhoto.Height = 600;
Canvas.SetLeft(imgPhoto, 1);
Canvas.SetTop(imgPhoto, 1);
this.Children.Add(imgPhoto);
//“后一頁(yè)”按鈕的設(shè)置
btnNext = new Button();
btnNext.Width = 150;
btnNext.Height = 20;
btnNext.Content = "后一頁(yè) >>";
btnNext.HorizontalContentAlignment = HorizontalAlignment.Center;
btnNext.VerticalContentAlignment = VerticalAlignment.Center;
btnNext.Cursor = Cursors.Hand;
Canvas.SetLeft(btnNext, 151);
Canvas.SetTop(btnNext, 605);
this.Children.Add(btnNext);
//頁(yè)碼文本的設(shè)置
PageNum = new TextBlock();
PageNum.Width = 100;
PageNum.Height = 20;
PageNum.Text = "00 / 00";
PageNum.TextAlignment = TextAlignment.Right;
PageNum.VerticalAlignment = VerticalAlignment.Center;
PageNum.FontFamily = new FontFamily("Comic sans MS");
Canvas.SetLeft(PageNum, 340);
Canvas.SetTop(PageNum, 607);
this.Children.Add(PageNum);
}
//設(shè)置圖片路徑
public void setterimgPhoto(string path)
{
BitmapImage btm = new BitmapImage();
btm.UriSource = new Uri(path, UriKind.Relative);
imgPhoto.Source = btm;
}
//設(shè)置按鈕是否可見
public void setterDisplayBtnNext(bool YesNo)
{
if (YesNo)
{
btnNext.Visibility = Visibility.Visible;
}
else
{
btnNext.Visibility = Visibility.Collapsed;
}
}
//設(shè)置頁(yè)碼
public void setterPageNumber(string currentPageNum, string TotalPageNum)
{
PageNum.Text = currentPageNum + " / " + TotalPageNum;
}
//返回按鈕單擊事件關(guān)聯(lián)
public Button getbtnNext()
{
return btnNext;
}
}
}
3、構(gòu)建應(yīng)用程序界面
詳細(xì)的說(shuō)明請(qǐng)見代碼注釋。
MainPage.xaml文件代碼:
Code
<UserControl x:Class="SilverlightClient.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SLMitsuControls;assembly=SLMitsuControls"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot">
<Canvas x:Name="layout" Background="White" Width="906" Height="630" Canvas.Left="0" Canvas.Top="0">
<!--顯示層-->
<Canvas x:Name="canvasBook" Background="White" Width="906" Height="630" Canvas.Left="0" Canvas.Top="0" Visibility="Collapsed">
<local:UCBook x:Name="book" Width="906" Height="630" Canvas.Left="0" Canvas.Top="0" /><!--BookControl-->
</Canvas>
<!--加載層-->
<Canvas x:Name="canvChanging" Width="500" Height="75" Canvas.Left="200" Canvas.Top="250" Visibility="Collapsed" Background="Transparent">
<TextBlock x:Name="changingText" Text="頁(yè)面加載中" Width="200" Height="30" Canvas.Left="0" Canvas.Top="0" FontFamily="comic sans ms" FontSize="14"></TextBlock>
<ProgressBar x:Name="changingProgressBar" Width="500" Height="30" Canvas.Left="0" Canvas.Top="30"></ProgressBar>
</Canvas>
</Canvas>
</Grid>
</UserControl>
4、設(shè)置應(yīng)用程序控制邏輯
詳細(xì)的說(shuō)明請(qǐng)見代碼注釋。
1)MainPage.xaml.cs文件代碼:
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
using SLMitsuControls;
namespace SilverlightClient
{
public partial class MainPage : UserControl, IDataProvider
{
//定義全局變量
private List<object> PageObjectList;//頁(yè)面對(duì)象列表
public enum PageType { right, left };//頁(yè)面類型
public string fileMedia = "";//文件媒體
public string headerPage = "";//首頁(yè)
public int maxiPageNum = 0;//最大頁(yè)數(shù)
public enum Location { local, web };//枚舉應(yīng)用程序所在
public Location modeLocation;
private int pageDownload = 0;//下載的頁(yè)面數(shù)
private string uriResources = "";//Uri地址
//構(gòu)造函數(shù)
public MainPage()
{
InitializeComponent();
PageObjectList = new List<object>();
}
//UserControl事件觸發(fā)處理
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
if (modeLocation == Location.local)
{
this.canvChanging.Visibility = Visibility.Collapsed;
this.canvasBook.Visibility = Visibility.Visible;
//填充頁(yè)面列表
FillPagesList();
}
if (modeLocation == Location.web)
{
this.canvChanging.Visibility = Visibility.Visible;
this.canvasBook.Visibility = Visibility.Collapsed;
//開始下載頁(yè)面
DownloadPages();
}
}
//開始將頁(yè)面填充至List中
private void FillPagesList()
{
//用頁(yè)面填充列表
for (int xx = 1; xx <= maxiPageNum; xx++)
{
if (xx % 2 != 0)
{
//前一頁(yè)即奇數(shù)頁(yè)
AddPageToList(PageType.right, fileMedia + "/" + headerPage + xx.ToString("00") + ".jpg", xx.ToString(),
maxiPageNum.ToString(), true);
}
else
{
//后一頁(yè)即偶數(shù)頁(yè)
AddPageToList(PageType.left, fileMedia + "/" + headerPage + xx.ToString("00") + ".jpg", xx.ToString(),
maxiPageNum.ToString(), true);
}
}
//移除最后一頁(yè)的按鈕
TypePage.RightPage page = PageObjectList[maxiPageNum - 1] as TypePage.RightPage;
page.setterDisplayBtnNext(false);
//為翻頁(yè)按鈕指派事件觸發(fā)處理
for (int xx = 1; xx < maxiPageNum; xx++)
{
if (xx % 2 != 0)
{
//前一頁(yè)即奇數(shù)頁(yè)
TypePage.RightPage pp = PageObjectList[xx - 1] as TypePage.RightPage;
Button btnNext = pp.getbtnNext();
btnNext.Click += new RoutedEventHandler(btnNext_Click);
}
else
{
//后一頁(yè)即偶數(shù)頁(yè)
TypePage.LeftPage pp = PageObjectList[xx - 1] as TypePage.LeftPage;
Button btnPrevious = pp.getbtnPrevious();
btnPrevious.Click += new RoutedEventHandler(btnPrevious_Click);
}
}
//為Book設(shè)置數(shù)據(jù)內(nèi)容
book.SetData(this);
}
//向頁(yè)面列表中添加具體頁(yè)面
private void AddPageToList(PageType pageType, string pathImage, string numPage, string numMaxiPage,
bool showBtnYesNo)
{
switch (pageType)
{
case PageType.right:
TypePage.RightPage pcd = new SilverlightClient.TypePage.RightPage();
pcd.setterimgPhoto(pathImage);
pcd.setterPageNumber(numPage, numMaxiPage);
pcd.setterDisplayBtnNext(showBtnYesNo);
PageObjectList.Add(pcd);
break;
case PageType.left:
TypePage.LeftPage pcg = new SilverlightClient.TypePage.LeftPage();
pcg.setterimgPhoto(pathImage);
pcg.setterPageNumber(numPage, numMaxiPage);
pcg.setterDisplayBtnPrevious(showBtnYesNo);
PageObjectList.Add(pcg);
break;
}
}
//“下一頁(yè)”按鈕事件觸發(fā)處理
private void btnNext_Click(object sender, RoutedEventArgs e)
{
book.AnimateToNextPage(500);
}
//“上一頁(yè)”按鈕事件觸發(fā)處理
private void btnPrevious_Click(object sender, RoutedEventArgs e)
{
book.AnimateToPreviousPage(500);
}
//從網(wǎng)絡(luò)上下載頁(yè)面
private void DownloadPages()
{
this.canvChanging.Visibility = Visibility.Visible;
this.uriResources = Application.Current.Host.Source.AbsoluteUri;
int index = uriResources.IndexOf("SilverlightClient.xap");
uriResources = uriResources.Substring(0, index);
this.changingProgressBar.Minimum = 0;
this.changingProgressBar.Maximum = maxiPageNum - 1;
string theResources = uriResources + fileMedia + "/" + headerPage + (pageDownload + 1).ToString("00") + ".jpg";
string theResourcesNum = headerPage + (pageDownload + 1).ToString("00") + ".jpg";
AsynchronouslyDownloadPage(theResources, theResourcesNum);
}
//異步下載頁(yè)面
private void AsynchronouslyDownloadPage(string path, string num)
{
WebClient unWeb = new WebClient();
unWeb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(unWeb_DownloadStringCompleted);
unWeb.DownloadStringAsync(new Uri(path));
this.changingText.Text = "正在下載 : " + num;
this.changingProgressBar.Value = this.pageDownload;
}
//異步下載頁(yè)面完成事件觸發(fā)處理
private void unWeb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
this.pageDownload++;
if (this.pageDownload < this.maxiPageNum)//持續(xù)不斷下載頁(yè)面直到所有頁(yè)面都下完
{
string theResources = uriResources + fileMedia + "/" + headerPage + (pageDownload + 1).ToString("00") + ".jpg";
string theResourcesNum = headerPage + (pageDownload + 1).ToString("00") + ".jpg";
AsynchronouslyDownloadPage(theResources, theResourcesNum);
}
else
{
FillPagesList();
this.canvChanging.Visibility = Visibility.Collapsed;
this.canvasBook.Visibility = Visibility.Visible;
}
}
//強(qiáng)制聲明接口
#region IDataProvider Members
public object GetItem(int index)
{
return PageObjectList[index];
}
public int GetCount()
{
return PageObjectList.Count;
}
#endregion
}
}
2)App.xaml.cs文件代碼:
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightClient
{
public partial class App : Application
{
public string gFileMedia = "";
public string gHeaderPage = "";
public int gPageNumber = 0;
public string gModeLocation = "";
public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;
InitializeComponent();
}
private void Application_Startup(object sender, StartupEventArgs e)
{
int paramOk = 0;
//從HTML中取出初始化數(shù)據(jù)
if (e.InitParams.ContainsKey("gFile"))
{
gFileMedia = e.InitParams["gFile"];
paramOk++;
}
if (e.InitParams.ContainsKey("gHeaderPage"))
{
gHeaderPage = e.InitParams["gHeaderPage"];
paramOk++;
}
if (e.InitParams.ContainsKey("gNum"))
{
string recup = e.InitParams["gNum"];
gPageNumber = int.Parse(recup);
paramOk++;
}
if (e.InitParams.ContainsKey("gLocation"))
{
gModeLocation = e.InitParams["gLocation"];
paramOk++;
}
if (paramOk == 4)
{
//初始化MainPage
MainPage maPage = new MainPage();
maPage.fileMedia = gFileMedia;
maPage.headerPage = gHeaderPage;
maPage.maxiPageNum = gPageNumber;
if (gModeLocation.CompareTo("local") == 0)
{
maPage.modeLocation = MainPage.Location.local;
}
if (gModeLocation.CompareTo("web") == 0)
{
maPage.modeLocation = MainPage.Location.web;
}
this.RootVisual = maPage;
}
}
private void Application_Exit(object sender, EventArgs e)
{
}
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (!System.Diagnostics.Debugger.IsAttached)
{
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
{
try
{
string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");
System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
}
catch (Exception)
{
}
}
}
}
3)在SilverlightClientTestPage.aspx文件(位于工程FlipPage文件夾下)中,添加用綠色粗體標(biāo)明的代碼:
<body>
<form id="form1" runat="server" style="height:100%">
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/SilverlightClient.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<!--設(shè)置Book初始化參數(shù)-->
<param name="initParams" value="gFile=mediaPictures, gHeaderPage=albumPictures, gNum=9, gLocation=web" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</form>
</body>
5、最終效果圖
我做出來(lái)后試了試,很不錯(cuò),源代碼中有N個(gè)錯(cuò)誤,我重新做了一個(gè)翻書實(shí)例,大家可以下載下來(lái)看看……
源代碼下載http://download.csdn.net/source/1961695
有問(wèn)題隨時(shí)歡迎交流……