本篇再補充一塊內容,就是自定義狀態的介紹。
自定義狀態用於封裝用戶控件在各種狀態之間切換時的外觀變化及其動畫效果,方便調用。比如有個用戶控件用於實現類似舞台幕布打開和關閉切換的效果,可以創建幕布關閉和幕布打開兩個狀態並編輯界面及動畫,然后調用狀態切換,就可以方便地實現幕布打開和關閉效果。下面看演示。
1. 首先創建一個用戶控件命名為CurtainControl,打開該用戶控件的xaml進行編輯。
2. 在狀態面板中,點擊添加狀態組按鈕,將新添加的狀態組命名為CurtainControlStateGroup,點擊添加狀態按鈕,添加兩個狀態,命名為CurtainOpened和CurtainClosed。
3. 點擊選擇狀態面板中的“基本”狀態項,將界面中的Grid分為四列,兩邊的兩列為0,中間的兩列為*,背景改為白色。在外層Grid內部放入兩個Border,分別在中間兩列,背景色改為某種徑向漸變色(為了演示方便,實際項目可精心設計),加個邊的顏色,最好抽取樣式。完成后代碼如下,
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:x:Class="BlendDemo.CurtainControl" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.Resources> <Style x:Key="CurtainStyle" TargetType="{x:Type Border}"> <Setter Property="Background"> <Setter.Value> <RadialGradientBrush> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="#FFFFC1C1" Offset="1"/> <GradientStop Color="#FF382B2B" Offset="0.223"/> <GradientStop Color="#FF755959" Offset="0.465"/> </RadialGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" Value="#FF00B9FF"/> <Setter Property="BorderThickness" Value="1"/> </Style> </UserControl.Resources> <Grid Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="0"/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition Width="0"/> </Grid.ColumnDefinitions> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CurtainControlStateGroup"> <VisualState x:Name="CurtainOpened"/> <VisualState x:Name="CurtainClosed"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Border Grid.Column="1" Style="{DynamicResource CurtainStyle}"/> <Border Grid.Column="2" Style="{DynamicResource CurtainStyle}"/> </Grid> </UserControl>
4. 點擊狀態面板中的CurtainControlStateGroup狀態組的打開FluidLayout按鈕(圖標為上下兩個波浪線),然后選擇CurtainOpened狀態項,進入動畫錄制狀態。將第一個Border的Grid.Column由1改為0,將第二個Border的Grid.Column由2改為3。
5. 點擊選擇狀態面板中的“基本”狀態項,退出動畫錄制狀態。將CurtainControlStateGroup狀態組的默認過度時間改為1s。
此時用戶控件已經完成,完整代碼如下。
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class ="BlendDemo.CurtainControl" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.Resources> <Style x:Key="CurtainStyle" TargetType="{x:Type Border}"> <Setter Property="Background"> <Setter.Value> <RadialGradientBrush> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="#FFFFC1C1" Offset="1"/> <GradientStop Color="#FF382B2B" Offset="0.223"/> <GradientStop Color="#FF755959" Offset="0.465"/> </RadialGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" Value="#FF00B9FF"/> <Setter Property="BorderThickness" Value="1"/> </Style> </UserControl.Resources> <Grid Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition Width="0"/> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition Width="0"/> </Grid.ColumnDefinitions> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CurtainControlStateGroup" ei:ExtendedVisualStateManager.UseFluidLayout="True"> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="0:0:1"/> </VisualStateGroup.Transitions> <VisualState x:Name="CurtainOpened"> <Storyboard> <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="border"> <EasingInt32KeyFrame KeyTime="0" Value="0"/> </Int32AnimationUsingKeyFrames> <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="border1"> <EasingInt32KeyFrame KeyTime="0" Value="3"/> </Int32AnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="CurtainClosed"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <VisualStateManager.CustomVisualStateManager> <ei:ExtendedVisualStateManager/> </VisualStateManager.CustomVisualStateManager> <Border x:Name="border" Grid.Column="1" Style="{DynamicResource CurtainStyle}"/> <Border x:Name="border1" Grid.Column="2" Style="{DynamicResource CurtainStyle}"/> </Grid> </UserControl>
6. 創建一個空的窗口,並設置為程序啟動窗口。在外層Grid中加入兩行,第一行為Auto,在其中放兩個Button(外面套一個橫向的StackPanel),文字改為打開和關閉。第二行為*,放入CurtainControl控件,在資產面板的“項目”分類中找,如果找不到該控件,請先生成項目。
7. 在資產面板中,選擇“行為”分類,拖動GoToStateAction到文檔大綱面板中的第一個Button上。在屬性面板中,點擊公共組下面的TargetName屬性的美工板元素選取器按鈕(圓圈中間有一個黑點),在美工板中選擇CurtainControl控件。點擊StateName屬性的下拉框,選擇CurtainOpened狀態。第二個Button也執行同樣的操作,StateName屬性選擇CurtainClosed狀態。
至此,演示示例已全部完成,Window1的代碼如下。
<Window 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:BlendDemo" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="BlendDemo.Window1" mc:Ignorable="d" Title="Window1" Height="322" Width="375"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <local:CurtainControl x:Name="curtainControl" Grid.Row="1"/> <StackPanel Orientation="Horizontal"> <Button Content="打開"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:GoToStateAction TargetName="curtainControl" StateName="CurtainOpened"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button Content="關閉"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:GoToStateAction TargetName="curtainControl" StateName="CurtainClosed"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </StackPanel> </Grid> </Window>
界面效果如下,
點擊打開和關閉按鈕試試效果吧。