2011年3月2日 星期三

2-2 Xaml指令碼與Silverlight元素

       不管是UIElementSilverlight Controls,都是透過XAML碼來描述,例如<Rectangle … />表示矩形(屬於UIElement)<Canvas …/>表示一個畫布容器(屬於Container)<Button … />表達一個按鈕控制項(屬於Controls)
       這些琳瑯滿目的物件,都是透過XAML指令碼描述的,包含屬性的設定,或是事件的指定等等,也都透過XAML指令碼來進行。所以在這一章當中,我們將基本的UIElement作一個整理,讀者僅需要概略的瀏覽過即可,若有需要時可以重新翻回來參考。

Xaml指令碼的架構


       如同您已經知道的,Xaml指令碼本身遵循著XML的格式,例如底下這個.xaml檔案中的內容是非常很典型的Xaml語法,Canvas表達的是一個容器:





呈現出來的結果如下:

       其中xmlnsxmlns:x是用來標示出Silverlight Xaml指令碼的命名空間,用以決定文件當中合法的Xaml指令碼規格。這些Xaml元素透過x:Name或是Name屬性(Attribute)來指定該元素的名稱,以方便未來透過程式碼控制。也就是說,所有將來你想要用程式碼控制的物件,都建議您加上名稱。

       同時,Xaml指令碼是區分大小寫的,且對結構的要求比HTML來的嚴謹。同一個Attribute不得出現兩次以上,例如底下這樣是不合法的撰寫方式:

如果重覆定義同樣的屬性,在VS2010的開發階段就會出現底下這樣的錯誤訊息:

Xaml的擴展屬性語法

       Xaml碼當中,部分的屬性支援擴展式的語法,例如,CanvasBackground屬性可以這麼寫,用以呈現出黃色的背景:


<Canvas
Width="640" Height="480"
   x:Name="Page"
   Background="Yellow">
(……)
</Canvas>



但是您也可以這麼寫:


       Background屬性給獨立出來,變成一組『<Canvas.Background>』標記,如此一來,就可以利用更複雜的描繪方式來呈現出漸層的背景。

這種模式相當常見,例如底下RectangleFill指令是用來設定填滿顏色:


但您也可以擴展成底下的方式用漸層來設定填滿顏色(改為<Rectangle.Fill>)

呈現出的結果如下:

如果是橢圓形的話,則語法就變成<Ellipse.Fill>

<Ellipse Width="205" Height="60" Stroke="#FF000000" Canvas.Left="8" Canvas.Top="82">
  <Ellipse.Fill>
    <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
      <GradientStop Color="#FFFFFFFF" Offset="0"/>
      <GradientStop Color="#FFEAFF00" Offset="1"/>
    </LinearGradientBrush>
  </Ellipse.Fill>
</Ellipse>

這種模式在Xaml指令碼中相當常見,請讀者特別留意。
備註:
其實不管是ASP.NET或是Silverlight,使用這樣的宣告式語法已經行之有年,過去開發Windows應用程式的時代,開發人員即便可以使用所視及所得的繪製工具(諸如VS2003, VS2005)來繪製,實際上還是把UI描述(位置、外觀、顏色)轉為程式碼來執行。所以你會看到Windows應用程式有『Form1.Designer.cs』這樣的檔案,其實就是UI描述被Visual Studio具體轉換成的程式碼檔案。
但這樣的描述其實維護起來相當困難,因此,ASP.NETSilverlight乃至於WPFUI描述均仿效HTMLXML方式呈現,當XML被載入記憶體之後,會從XML文件的節點最末端開始解析,例如看到上述的『LinearGradientBrush』就產生一個LinearGradientBrush物件,接著看到Ellipse再產生一個物件,然後把剛才的LinearGradientBrush物件填入Ellipse物件的Fill屬性,以達成我們需要的操作介面。


Xaml指令碼中的事件指定
       

       Xaml指令碼除了描繪出圖形化的介面之外,還可以透過指定『事件』處理函式來和後端C#/VB程式碼配合,例如:


       上面這段Xaml指令碼中的Rectangle元素『R1』設定了『MouseLeftButtonDown』事件的處理函式為:『R1_Click』。

因此,只要配合底下的Code Behind程式碼檔案(.xaml.cs.xaml.vb)
private void R1_Click(object sender, MouseButtonEventArgs e)
{
    //在其中撰寫程式碼...
    MessageBox.Show("R1被按下");
}


       中撰寫程式碼,當元素『R1』被點選(MouseLeftButtonDown事件被觸發)時,則會執行到對應的指令:

       Silverlight當中每一個UIElement都有許多事件可以使用,由於Rectangle這些UIElementSilverlight中最基礎的元素,因此其時不具備Click事件,取而代之的是MouseLeftButtonDown事件,在Silverlight當中,這些基礎UIElement所常用的事件包含:

事件名稱
意義
MouseLeftButtonDown
滑鼠按下
MouseLeftButtonUp
滑鼠放開
MouseEnter
滑鼠進入元素上
MouseLeave
滑鼠從元素上離開
MouseMove
滑鼠在元素上移動(經過)
KeyDown
鍵盤按下
KeyUp
鍵盤放開
Loaded
元素被載入


這些事件我們會在後面的章節中仔細討論。

備註:
請注意,先前我們曾經介紹過Button控制項,由於該控制項並非上述Silverlight中的基礎元件,而是透過繼承ButtonBase類別而來,因此MouseLeftButtonDown等事件已經取消,取而代之的是Click事件。

沒有留言:

張貼留言