VisualState基本使用
首先搭建一个自定义控件,继承自ContentControl
,自动生成了这些文件
由于CustomButton
在Custom
命名空间中,所以改一下xaml中的引用
xmlns:local="clr-namespace:WpfApp1.Custom"
- 定义部件和视觉状态
TemplatePart
是模板中的部件名
TemplateVisualState
是模板中的样式名
[TemplatePart(Name = "P_Border")]
[TemplateVisualState(Name = mouseoverstate, GroupName = mousegroup)]
[TemplateVisualState(Name = mouseleavestate, GroupName = mousegroup)]
public class CustomButton : ContentControl
{
public const string mouseoverstate = "mouseover";
public const string mouseleavestate = "mouseleave";
public const string mousegroup = "mousegroup1";
}
- 添加样式
推荐把视觉状态放在模板的根元素下,这个例子中是Border
需要注意的是,由于使用了(Border.Background).(SolidColorBrush.Color)
,所以Border
的Background
必须有个预设值
<Style TargetType="{x:Type local:CustomButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomButton}">
<Border
x:Name="P_Border"
Padding="5"
CornerRadius="5"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0">
<TextBlock Text="{TemplateBinding Content}" Foreground="White" HorizontalAlignment="Center"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="mousegroup1">
<!--GoToState第三个参数useTransitions为false时进入这里-->
<VisualState x:Name="mouseover">
<Storyboard>
<ColorAnimation Storyboard.TargetName="P_Border" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Duration="0:0:0" To="#FF16b777"/>
</Storyboard>
</VisualState>
<VisualState x:Name="mouseleave">
<Storyboard>
<ColorAnimation Storyboard.TargetName="P_Border" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Duration="0:0:0" To="#CC16b777"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
- 后台代码
这里在鼠标事件中改变视觉状态
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
VisualStateManager.GoToState(this, mouseleavestate, false);
}
protected override void onm ouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
VisualStateManager.GoToState(this, mouseoverstate, false);
}
protected override void onm ouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e);
VisualStateManager.GoToState(this, mouseleavestate, false);
}
- 效果
增加VisualTransition过渡效果
但这没有过渡,添加过渡需要设置GoToState(this, mouseoverstate, true)
同时还要添加过渡效果的xaml元素
<VisualStateGroup x:Name="mousegroup1">
<!--GoToState第三个参数useTransitions为true时进入这里-->
<VisualStateGroup.Transitions>
<!--from是前一个状态名,to是后一个状态名-->
<VisualTransition To="mouseover">
<Storyboard>
<!--(Border.Background).(SolidColorBrush.Color)是PropertyPath类型限定的单个属性语法,格式为(targetTtype.property)-->
<ColorAnimation Storyboard.TargetName="P_Border" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Duration="0:0:1" To="#FF167777"/>
</Storyboard>
</VisualTransition>
<VisualTransition To="mouseleave">
<Storyboard>
<ColorAnimation Storyboard.TargetName="P_Border" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Duration="0:0:1" To="#AA167777"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<!--GoToState第三个参数useTransitions为false时进入这里-->
<VisualState x:Name="mouseover">
<Storyboard>
<ColorAnimation Storyboard.TargetName="P_Border" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Duration="0:0:0" To="#FF167777"/>
</Storyboard>
</VisualState>
<VisualState x:Name="mouseleave">
<Storyboard>
<ColorAnimation Storyboard.TargetName="P_Border" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Duration="0:0:0" To="#AA167777"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
再把GoToState(this, mouseoverstate, false)
改为true
但注意OnApplyTemplate
中不要改,因为那里是首次加载,许需要过渡
- 效果