Silverlight中的ControlTemplate介绍了ControlTemplate的相关的几个知识,这篇继续介绍剩余的内容
上文我们已经为Tooltip的ControlTemplate添加了视觉状态管理,结构如下:
<ControlTemplate TargetType="ToolTip">
<Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="OpenStates">
<VisualState x:Name="Closed">
<Storyboard>
<ColorAnimation ...></ColorAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="Open">
<Storyboard>
<ColorAnimation ...></ColorAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
在应用了VisualState的ControlTemplate中ToolTip中,当你的ToolTip状态为Open时,直到1秒钟之后你才会看到设置的动画效果,
因为在默认状态下,动画要在1秒后才开始。如果需要立即体验到这种动画效果,这就用到了视觉状态迁移这个概念。
VisualTransition
把VisualTransition添加到ControlTemplate中,可以指定动画的延迟时间,从而使一种状态平滑的转移到另一种状态。 VisualTransition常用的属性为From【从哪个状态开始】,To【迁移到何种状态】,GeneratedDuration【间隔时长】。
以ToolTip为例,下面的Xaml表示当ToolTip进入打开状态时需要百分之一秒的时间<VisualTransition To="Open" GeneratedDuration="0:0:0.1" />
通过设置 To 和 From 属性,可以设置过渡的时间。
<VisualTransition From="Open" To="Closed" GeneratedDuration="0:0:0.5"/>
可以将VisualTransition限制为仅应用于某些状态,SDK上有关于这个限制的说明
VisualStateGroup
如果要应用多个 VisualTransition,则可以在VisualStateGroup.Transitions属性中进行设置.
<VisualStateGroup.Transitions>
<VisualTransition To="Closed"
GeneratedDuration="0:0:0.1" />
<VisualTransition Form="Open" To="Closed"
GeneratedDuration="0:0:0.2" />
</VisualStateGroup.Transitions>
这里需要注意2点:如果From,To里面设置的是VisualStateGroup里不存在的视觉状态名称,则会忽略该VisualTransition。
在 VisualStateGroup 中可以有多个引用同一状态的 VisualTransition对象,但是将按上图中指定的顺序使用它们,
因为在ToolTip中仅仅有2个视觉状态,不够直观,这里我们引用Button的视觉状态进行说明
<VisualTransition To="MouseOver"
GeneratedDuration="0:0:0.1" />
<VisualTransition From="Pressed" To="MouseOver"
GeneratedDuration="0:0:0.2" />当Button从Pressed状态转换为MouseOver时,使用第2个视觉迁移,从非Pressed状态进入MouseOver时,则会使用第1个视觉状态。
在VisualTransition 包含还一个当控件转换状态时开始时的 Storyboard属性:
<VisualTransition From="MouseOver" To="Normal"
GeneratedDuration="0:0:1.5">
<Storyboard>
<ColorAnimationUsingKeyFrames …/>
</Storyboard>
</VisualTransition>
TemplatePartAttribute
上文在结束时提到了TemplateVisualStateAttribute这个特性,其实还有一个比较重要的特性TemplatePartAttribute,
有时候控件的内部逻辑需要对ControlTemplate中某个FrameworkElement进行事件处理,这时候就出现了控件协定这个概念。
在Silverlight中,控件使用 TemplatePartAttribute传递期望使用的元素的类型,以及元素应具有的名称。
如果你看ListBox的定义就会看到:
这个概念其实很好解释的,以ListBox为例,它内部的逻辑需要在其ContentTemplate中找到Name属性为ScrollViewer的ScrollViewer。
查看ListBox的ControlTemplate,你会看到这部分的XAML
<ControlTemplate TargetType="ListBox">
...
<Border >
<ScrollViewer x:Name="ScrollViewer" >
<ItemsPresenter/>
</ScrollViewer>
</Border>
...
</ControlTemplate>
好了,这篇暂时写到这里,最后结合两篇文章控件ControlTemplate中涉及的VSM的相关知识:
<ControlTemplate TargetType="...">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup.Transitions>
<VisualTransition From="" GeneratedDuration="">
<VisualTransition From="" GeneratedDuration="">
</VisualStateGroup.Transitions>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!--Other FrameworkElement-->
...
</Grid>
</ControlTemplate>
来源:https://www.cnblogs.com/626498301/archive/2010/12/03/1895320.html