[Silverlight] 新人學Silverlight 4 (5)–用Silverlight做出jQuery Carousel效果
昨天上課幾乎都是在講Blend裡控制項的操作
想說我若漫無目的跟著介紹Blend裡控制項屬性的話,似乎也太乏味
乾脆找一個範例(jQuery Carousel)來同時學習
(1)Blend的操作
(2)三個基本容器的佈局(Grid、StackPanel、Canvas)
(3)圖形工具的使用
(4)撰寫程式碼展示動畫
(1)Blend的操作
打開Blend>新增專案
之後會看到以下畫面(順便介紹個人常用熱鍵)
(2)三個基本容器的佈局(Grid、StackPanel、Canvas)
Canvas:類似CSS的
position:absolute;
left:xxx px;
top:xxx px;
絕對座標定位,要用程式碼移動控制項的話,建議先把控制項放入Canvas容器(就像要用jQuery animate函式之前,要先把元素CSS的position改為absolute)。
Grid:類似Html Table的拆版,透過行與列所建立的表格區域定位。
StackPanel:水平與垂直兩種方向的堆疊排列,通常使用在表單設計。
(3)圖形工具的使用
先在畫板畫出三個正方形,並在正方形中間各別寫下Red、Yellow、Green三個字
(同理,要畫出正圓形的話,按住Shift鍵拖拉即可)
接著右方的屬性面板,點選紅色來填滿
然後再點選左方的資產面板,找到TextBlock
把TextBlock放入該Border中間並輸入Red
右方的屬性面板可以挑選字型,請見以下說明
如果沒有選擇內建字型的話,通常還得再做一個「勾選內嵌」動作確保Silverlight發佈後,某些使用者看到的字型不會跑掉
不過內嵌字型會造成.xap檔膨大
詳見:Blend 4 內嵌字體 by edenyeh
另外,為什麼不用Rectangle而用Border畫正方形?
請見MSDN討論Silverlight里的Rectangle与border有啥区别呀?
在此範例中,稍後用程式碼可能要移動正方形時連同TextBlock一起移動,所以選擇Border當TextBlock的容器,Rectangle則不能當容器
接下來相同做法畫出另兩個Yellow、Green,並且把這三個正方形放入水平排列的StackPanel容器內
接著把紅色正方形拖拉進StackPanel
複製現有Border的XAML碼,貼在StackPanel內,並更改顏色和文字
因為待會程式碼要移動StackPanel,所以再使用Canvas包住StackPanel
再使用ScrollViewer容器包住Canvas做遮蔽效果
把Canvas拖拉進ScrollViewer後,完成的XAML如下
上圖就很像以往在Html 撰寫Carousel效果時候
ScrollerViewer=>有捲軸的div容器
StackPanel => ul容器
Canvas=>讓ul容器可以移動
接著,來畫左右箭頭Button
右方屬性面板
並在下方(見上圖),「外觀」面板下改變Opacity為50% (不透明度:0%完全透明,100%完全明顯)
再從左方資產面板
一樣的方式,在Border內畫一個三角形
再對著Border右鍵>變成控制項(轉成範本)
接著才是真正要擺上Button套用此範本
剛剛Blend自己產生的Button可以刪除了
Button可以從資產面板中拖拉出來
另一個Button可以用變型選取工具旋轉角度,兩個Button再稍做調整位置如下
如果這時候建置專案用F5執行來看的話會發現,當滑鼠移到Button上面時什麼反應都沒有
以下介紹Visual State Manager用法
先點選任意一個套用MyButtonStyle1的Button
右鍵>編輯範本>編輯目前的項目
右方屬性面板,隨便挑一個顏色當作MouseOver時的顏色
點選「物件與時間軸」面板的按鈕,以離開範本編輯模式
接下來按Ctrl+Shift+B建置並F5執行,確認滑鼠移過Button有效果後
要再為兩個Button加入事件處理函式
點選Button>右方屬性面板
using System;
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.Shapes;
namespace SL_Carousel
{
public partial class MainPage : UserControl
{
public MainPage()
{
// 必須將變數初始化
InitializeComponent();
}
private void btnLeft_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: 在此新增事件處理常式執行項目。
}
private void btnRight_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: 在此新增事件處理常式執行項目。
}
}
}
至此Blend的控制項製作告一段落
(4)撰寫程式碼展示動畫
用Visual Studio 2010開啟剛剛的.sln
打開MainPage.xaml.cs
兩個Button的Click事件加入以下程式碼,先瞭解大概怎麼更改StackPanel的位置
private void btnLeft_Click(object sender, System.Windows.RoutedEventArgs e)
{
double currentLeft = Convert.ToDouble(myStackPanel.GetValue(Canvas.LeftProperty));
myStackPanel.SetValue(Canvas.LeftProperty, currentLeft - 100);
}
private void btnRight_Click(object sender, System.Windows.RoutedEventArgs e)
{
double currentLeft = Convert.ToDouble(myStackPanel.GetValue(Canvas.LeftProperty));
myStackPanel.SetValue(Canvas.LeftProperty, currentLeft + 100);
}
現在執行專案的話,雖然有切換正方形但沒有動畫效果
要手寫動畫效果的話,加入以下程式碼
private void btnLeft_Click(object sender, System.Windows.RoutedEventArgs e)
{
this.myAnimation("left");
}
private void myAnimation(string leftRight)
{
//目前myStackPanel相對於Canvas容器的Left值
double currentLeft = Convert.ToDouble(myStackPanel.GetValue(Canvas.LeftProperty));
//手寫動畫,把握兩個物件:Storyboard、DoubleAnimation
Storyboard sb = new Storyboard();
double endValue = (leftRight == "left") ? (currentLeft - 100) : (currentLeft + 100);
DoubleAnimation da = new DoubleAnimation()//DoubleAnimation初始化要給三個值
{
From = currentLeft,//起始值
To = endValue,//結束值
Duration = new TimeSpan(0, 0, 0, 0, 200)//多久完成
};
Storyboard.SetTarget(da, myStackPanel);//動畫作用對象(因為是myStackPanel要移動)
Storyboard.SetTargetProperty(da, new PropertyPath(Canvas.LeftProperty));//移動依據哪個Property
sb.Children.Add(da);//腳本加入動畫
sb.Begin();// 腳本開始播放
}
private void btnRight_Click(object sender, System.Windows.RoutedEventArgs e)
{
this.myAnimation("right");
}
現在執行專案的話,點選左右箭頭時,圖片的移動就有動畫效果了(只是以下圖片看不出來)
剩下的,當點選同一個箭頭超過2次,不能再移動圖形的防呆寫法就不累述
自問自答:
Q:我好像看到Canvas容器下的StackPanel可以輸入Canvas.Top、Canvas.Left,這是什麼意思?
A:此為Attached Property,對StackPanel而言,當它出現在Canvas中時才擁有Top和Left屬性,意即:依附在某個容器中才得到的屬性。