Visual State Manager (VSM-視覺狀態管理器) 之支持
Silverlight 和 WPF中的控件模板支持對控件的「look(外觀)」,以及控件的「feel(感覺)」的定製。「feel」之謂,我指的是改變它交互的響應性。例如,在按下時,得到焦點時,失去焦點時,處於按下的狀態時,處於不可用(disabled)狀態時,內中有東西被選中時。。。,它是如何反應的。經常地,在用戶象這樣與控件做交互時,你要執行動畫效果。
我們在Silverlight 2 Beta2中引進的一個新東西是"Visual State Manager(視覺狀態管理器)" (VSM),該功能將極大地方便你建造交互性的控件模板。VSM引入了你可在控件模板中利用的2個基本概念:"視覺狀態(Visual States)" 和 "狀態遷移(State Transitions)"。例如,象按鈕這樣的控件爲自己定義了多個視覺狀態: "Normal(正常)", "MouseOver(鼠標之下)", "Pressed(按下)", "Disabled(不可用)", "Focused(獲取焦點)", "Unfocused(不具焦點)"。在Blend中的模板編輯模式下,設計師現在可以輕鬆地編輯按鈕在每個特定狀態下的外觀,以及設置遷移規則來控制從一個狀態遷移到另一個狀態時動畫效果應該運行的時間。然後在運行時,Silverlight會動態地運行合適的動畫故事板來把控件從一個狀態平滑地過渡到另一個狀態。
這個模型很棒的地方是,設計師不用編寫代碼,不用手工創建動畫故事板,也不用理解控件的對象模型就可以非常有效率。這使得學習創建交互性控件模板的曲線非常容易,意味着現有的美工可以輕鬆地參與Silverlight項目。今年稍後,我們還將往WPF中添加"Visual State Manager(視覺狀態管理器)" (VSM)的支持,讓你在Windows應用中使用同樣的方法,以及在 WPF 和 Silverlight 項目間共享控件模板。
要看這個的實戰例子,讓我們往設計表面上加一個Button控件:
 
然後,我們可以右擊按鈕控件,編輯它的控件模板。我們將不從現有的默認控件模板開始(就象上面的Slider例子一樣),讓我們創建一個空白的控件模板,從頭做起:
Blend會提示我們給要創建的樣式(Style)資源取一個名字,我們將它取名爲「ScottButton」,點擊OK。這會把設計器置於按鈕的控件編輯模式下,一開始只有一個空白的控件模板:
上面有一樣需要注意的東西是,在Blend中有一個新的「States(狀態)」窗口,這個窗口會顯示Button控件提供的所有的「Visual States(視覺狀態)」。在上面,當前被選中的是「Base(基底)」狀態,該狀態允許我們定義我們的按鈕控件模板常用的視覺樹。
然後,我們可以往我們的基底狀態中加一些矢量元素,來定義象下面這樣的定製按鈕的外觀。我們可以使用由Blend提供的內置矢量繪製工具支持來設計這些圖形,或者使用Expression Design 或 Adobe Illustrator來建造矢量圖形,然後將其導入Blend中。下面,我們在我們的控件模板中加了4個「Path」元素,一個是帶圓角的背景(其名爲「background」),另一個帶陰影(drop shadow)(其名爲「shadow」),還有一個是帶40%蔽光性的「shine」(在頂部加了一些暈光),再有一個定義了默認的內部內容(在這個情形下,是個房子的圖案):
注:我們也可以導入一個圖片,但使用矢量元素會給予我們以後對按鈕進行擴縮/轉換,在任意分辨率或尺度上保持清晰觀感的靈活性(特別是在Silverlight移動設備的場景下,屏幕的分辨率大不相同或較小時,尤其有用),還允許我們對美工設計中的任何矢量元素可以輕易地做動畫效果或改動。
完成設計上面的基底狀態之後,我們可以按F5在瀏覽器中運行應用:
 
你可以在上面看到,我們的按鈕控件現在擁有一個比較好看的外觀。儘管它有了一個新的外觀,但按鈕依然象以前那樣觸發同樣的焦點,點擊,和懸浮事件,所以,使用按鈕的開發人員在操作使用了我們的新控件模板的按鈕時,不用改動任何代碼。
但我們的新按鈕控件模板的一個缺點是,它並不是交互的。這意味着,如果按鈕獲得/失去焦點,或者鼠標懸浮其上時,我得不到任何視覺反饋。點擊時,我也得不到很好的按下/彈起的動畫效果。
要將交互性加到我們的按鈕上,我們將回到Blend中,再次操作我們按鈕的控件模板。之前我們把矢量圖形元素加到了我們按鈕的「Base(基底)」狀態中,這允許我們定義所有視覺狀態的默認視覺外觀。我們現在將回去,進一步定製個別的按鈕視覺狀態。
例如,爲實現按鈕的mouse-over行爲,我們可以在「States」窗口中選擇「MouseOver」狀態,然後細調按鈕處於該狀態時的外觀。在下面,我選了控件模板中的「shine」矢量元素,調整它在屬性網格中的Opacity屬性,使其在MouseOver狀態下可見度更高。注意Blend是如何在對象窗口中,自動使用紅點加亮「shine」元素,然後在該元素的下面列出了Opacity屬性的。這可以便利很快地跟蹤我們在控件模板中在「Base(基底)」狀態和「MouseOver」狀態間所做的所有變動:
 
 
然後,我們可以在「States」窗口中選擇「Pressed」狀態,定製按鈕處於按下狀態時的外觀。我們將改變「Base(基底)」狀態的2樣東西,第一個變動是使得「shine」元素可見(就象MouseOver狀態一樣),第二個變動是稍微偏移按鈕控件的內容,同時保持影子元素不動。這會給予按鈕一個很好看的「depressed(按下)」外觀,與它的基底視覺形成很好的反差:
我們可以這樣來實現偏移變動: 在設計器中選擇background,content和shine元素,然後在屬性瀏覽器中對它們施加一個偏移顯示轉換(offset render transform):
現在,在瀏覽器中再次運行我們的應用的話,我們會發現我們的按鈕在使用時有交互的視覺反饋了。下面是我們按鈕的「Normal(正常)」外觀:
將鼠標懸浮於按鈕之上,會造成象下面這樣的發光效果:
點擊按鈕會導致它按下去,隱藏影子(在鬆開鼠標按鈕時,它會彈回來):
注意,我們不用編寫任何代碼或XAML來改變我們按鈕的觀感,新的視覺狀態管理器功能會自動地爲我們處理視覺狀態間的過渡。
在默認情形下,在你從一個視覺狀態移動到另一個視覺狀態時,Silverlight會動態地爲你構建和運行過渡Storyboard(提供了2個狀態間的平滑過渡動畫效果),你不需編寫任何代碼就可以讓這一切發生(注:如果你想的話,你還是能降低層次(drop down),加一個定製的Storyboard過渡,但在大多數情形下,你大概可以使用自動的Storyboard過渡)。
Silverlight的自動過渡功能中你可以利用的一個特性是,定製視覺狀態過渡發生所花的時間,你可以這麼做,點擊視覺狀態右邊的箭頭,設置一個規則來控制當從一個特定狀態移到另一個狀態時,過渡動畫效果應該運行的時間。
例如,我們可以加如下的規則來表示,我們要它花0.2秒鐘的時間來從"Normal"過渡到"MouseOver"視覺狀態:
 
 
然後,我們可以象這樣來配置這個規則,在Normal->MouseOver間過渡時花0.2秒鐘:
然後,我們可以點擊"MouseOver"狀態,設置一個規則,導致從MouseOver->Normal的過渡花0.4秒鐘:
現在,當我們重新運行應用時,對MouseOver場景,我們將有一個慢了一點的動畫過渡,給我們的應用添加了一種稍微更加平滑和更爲精緻的感覺。我們不用編寫一行代碼就可以促成這個效果。 隨Silverlight 2發佈的所有控件都有對象上面這樣的控件模板和視覺狀態管理器之定製的內置支持。
想進一步瞭解新的視覺狀態管理器和控件模板編輯功能的話,請看一下 這裏 和 這裏的教程, 以及這裏, 這裏 和 這裏的相關錄像。