. 功能需求
使用TemplatePart實(shí)現(xiàn)上篇文章的兩個(gè)需求(Header為空時(shí)隱藏HeaderContentPresenter,鼠標(biāo)沒(méi)有放在控件上時(shí)HeaderContentPresent半透明),雖然功能已經(jīng)實(shí)現(xiàn),但這樣實(shí)現(xiàn)的話基本上也就別想擴(kuò)展了。譬如開(kāi)發(fā)者做不到通過(guò)繼承或修改ControlTemplate實(shí)現(xiàn)如下功能:
半透明時(shí)的Opacity不是0.7,而是0.5。
半透明和不透明之前切換時(shí)有漸變動(dòng)畫。
當(dāng)然也并不是不可以用代碼實(shí)現(xiàn)這些需求,只是會(huì)復(fù)雜很多。大部分的開(kāi)發(fā)者都是對(duì)C#熟悉,對(duì)XAML陌生,很容易就選擇盡量使用C#實(shí)現(xiàn)全部功能,將所有功能集中在同一個(gè)地方并用熟悉的語(yǔ)言處理,當(dāng)然也有這樣做的優(yōu)點(diǎn),不過(guò)既然在用XAML平臺(tái),就應(yīng)該盡可能利用XAML平臺(tái)UI和代碼分離的優(yōu)點(diǎn)。
這篇文章用ContentView2示例講解VisualState如何實(shí)現(xiàn)上述的需求,ContentView2和上篇文章的ContentView一樣繼承自HeaderedContentControl。
2. VisualState
在實(shí)現(xiàn)需求前首先解釋VisualState的概念。
VisualState 指定控件處于特定狀態(tài)時(shí)的外觀??丶拇a指定控件處于何種狀態(tài),控件的ControlTemplate中根節(jié)點(diǎn)包含VisualStateManager.VisualStateGroups附加屬性,并在其中確定各個(gè)VisualState的外觀。
以CheckBox為例,CheckBox基本上包含Unchecked、Checked、Indeterminate三種狀態(tài),它通過(guò)IsChecked的值在這三種狀態(tài)中轉(zhuǎn)換。
這三種狀態(tài)的外觀如下所示:
實(shí)際上Checkbox的VisualState復(fù)雜很多,這里是簡(jiǎn)化的模型。
3. 確定VisualState
要使用VisualState,首先要明確控件中包含哪些VisualState。在ContentView2中有兩組VisualState:
CommonStates: 默認(rèn)是“Normal”,當(dāng)鼠標(biāo)進(jìn)入控件時(shí)是“PointerOver”。
HeaderStates: 默認(rèn)是“NoHeader”,當(dāng)Header屬性的值不為空時(shí)是“HasHeader”。
其中“CommonStates”、“HeaderStates”稱為VisualStateGroup,“Normal”、“PointerOver”等稱為VisualState。在同一個(gè)VisualStateGroup中的VisualState是互