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
<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 OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
VisualStateManager.GoToState(this, mouseoverstate, false);
}
protected override void OnMouseLeave(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
中不要改,因為那裡是首次載入,許需要過渡
- 效果