Silverlight - 视觉状态
如果您的用户能够知道应用程序的哪一部分可能响应输入,那就太好了。 在某种程度上,这可以通过使按钮看起来像按钮来完成。 如果某些东西看起来可以点击,那么它很可能是可以点击的。
但是,现代用户界面设计中的一个惯例是,用户界面元素还应该表示愿意在鼠标移到其父元素上时通过更改其父元素来进行响应。
例如,当鼠标移动时,内置按钮控件会稍微更改其背景,以暗示它是交互式的,然后在单击时进一步更改父级以使其看起来像被选中。 几乎所有控件都需要执行此操作,设计人员需要一种方法来创建和编辑动画以实现此目的。
状态和状态组
让我们看一个实际视觉状态的示例。 考虑一个复选框。 它可以是未选中或选中的,如果您选择,它可以支持第三种不确定状态。 对于所有三种情况,控件都需要看起来不同。 因此,我们有三种视觉状态。
![状态组复选框](/silverlight/images/state_group_checkbox.jpg)
为了证明它已准备好响应用户输入,当鼠标移到该复选框上时,该复选框的外观会略有变化,而当鼠标保持在该位置时,该复选框的外观会进一步变化。 如果该复选框被禁用,则必须考虑第四种状态,它看起来很棒并且表明它不会响应用户输入。
![更改复选框](/silverlight/images/changes_checkbox.jpg)
因此,我们这里还有另外四个状态。 在任何给定时间,复选框的视觉状态必须为正常、鼠标悬停、选中或禁用。 同时,它必须是已选中、未选中或不确定。
视觉状态管理器
由于其模板定义了控件的外观,因此模板需要定义每个视觉状态会发生什么。 到目前为止我们看到的模板不包含此类信息。 因此,控件的外观保持静态,无论其当前状态如何。
要将视觉状态添加到模板,首先要添加属性元素。
对于视觉状态处理,您可以做的最简单的事情就是定义当控件进入特定状态时将运行的动画。
控件每当更改状态时都会通知视觉状态管理器类。
然后,视觉状态管理器查看模板的这一部分并找出要运行的动画。
因此,当复选框进入鼠标悬停状态时,该动画将运行,从而更改模板某些部分的颜色。
让我们看一个简单的示例,通过使用可视状态机制为反映状态更改的复选框制作自定义模板。
下面给出的是带有视觉状态的复选框自定义模板的XAML代码。
<UserControl xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" x:Class = "CheckboxVisualState.Page" Width = "640" Height="480" xmlns:vsm = "clrnamespace:System.Windows;assembly = System.Windows" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable = "d"> <UserControl.Resources> <ControlTemplate x:Key = "CheckBoxControlTemplate1" TargetType = "CheckBox"> <Grid> <vsm:VisualStateManager.VisualStateGroups> <vsm:VisualStateGroup x:Name = "FocusStates"> <vsm:VisualState x:Name = "ContentFocused"/> <vsm:VisualState x:Name = "Focused"/> <vsm:VisualState x:Name = "Unfocused"/> </vsm:VisualStateGroup> <vsm:VisualStateGroup x:Name = "CommonStates"> <vsm:VisualStateGroup.Transitions> <vsm:VisualTransition GeneratedDuration = "00:00:00.5000000"/> </vsm:VisualStateGroup.Transitions> <vsm:VisualState x:Name = "MouseOver"> <Storyboard> <ColorAnimationUsingKeyFrames BeginTime = "00:00:00" Duration = "00:00:00.0010000" Storyboard.TargetName = "background" Storyboard.TargetProperty = "(Shape.Fill). (SolidColorBrush.Color)"> <SplineColorKeyFrame KeyTime = "00:00:00" Value = "#FFFF0000"/> </ColorAnimationUsingKeyFrames> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name = "Pressed"> <Storyboard> <ColorAnimationUsingKeyFrames BeginTime = "00:00:00" Duration = "00:00:00.0010000" Storyboard.TargetName = "background" Storyboard.TargetProperty = "(Shape.Fill). (SolidColorBrush.Color)"> <SplineColorKeyFrame KeyTime = "00:00:00" Value = "#FFCEFF00"/> </ColorAnimationUsingKeyFrames> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name = "Disabled"/> <vsm:VisualState x:Name = "Normal"/> </vsm:VisualStateGroup> <vsm:VisualStateGroup x:Name = "CheckStates"> <vsm:VisualStateGroup.Transitions> <vsm:VisualTransition GeneratedDuration = "00:00:00.5000000"/> </vsm:VisualStateGroup.Transitions> <vsm:VisualState x:Name = "Checked"> <Storyboard> <DoubleAnimationUsingKeyFrames BeginTime = "00:00:00" Duration = "00:00:00.0010000" Storyboard.TargetName = "checkPath" Storyboard.TargetProperty = "(UIElement.Opacity)"> <SplineDoubleKeyFrame KeyTime = "00:00:00" Value = "1"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name = "Unchecked"/> <vsm:VisualState x:Name = "Indeterminate"/> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> <Grid.ColumnDefinitions> <ColumnDefinition Width = "Auto"/> <ColumnDefinition Width = "3.61782296696066"/> <ColumnDefinition Width = "Auto"/> </Grid.ColumnDefinitions> <Canvas Height = "50" HorizontalAlignment = "Left" VerticalAlignment = "Top" Width = "50"> <Rectangle Height = "33.746" x:Name = "background" Width = "33.746" Canvas.Left = "8.452" Canvas.Top = "7.88" Fill = "#FFFFFFFF" Stroke = "#FF000000" RadiusX = "5.507" RadiusY = "5.507"/> <Path Height = "40.25" x:Name = "checkPath" Width = "39.75" Opacity = "0" Canvas.Left = "5.959" Canvas.Top = "7.903" Stretch = "Fill" Stroke = "#FF1F9300" StrokeThickness = "3" Data = "M1.5,1.5 C15.495283,8.7014561 27.056604,18.720875 33.75,33.75 M36,3.75 C22.004717,10.951456 10.443395,20.970875 3.7499986,36"/> </Canvas> <ContentPresenter HorizontalAlignment = "Left" Margin = "{TemplateBinding Padding}" VerticalAlignment = "{TemplateBinding VerticalContentAlignment}" Grid.Column = "2" Grid.ColumnSpan = "1" d:LayoutOverrides = "Height"/> </Grid> </ControlTemplate> </UserControl.Resources> <Grid x:Name = "LayoutRoot" Background = "White" > <CheckBox HorizontalAlignment = "Left" Margin = "52.5410003662109,53.5970001220703,0,0" VerticalAlignment = "Top" Template = "{StaticResource CheckBoxControlTemplate1}" Content = "CheckBox"/> </Grid> </UserControl>
当上述代码编译并执行后,您将看到以下网页,其中包含一个复选框。
![模板复选框](/silverlight/images/template_checkbox.jpg)
当光标进入复选框区域时,会改变状态。
![更改状态](/silverlight/images/change_state.jpg)
当您单击复选框时,您将看到以下状态。
![执行更改状态](/silverlight/images/execute_change_state.jpg)
我们建议您执行上面的示例以更好地理解。