控件的代码指定控件处于何种状态,控件的ControlTemplate中根节点包含VisualStateManager.VisualStateGroups附加属性,并在其中确定各个VisualState的外观 VisualStateManager VisualStateManager用于管理VisualState并操作它们之间的转换。 , useTransitions); if (Header == null) VisualStateManager.GoToState(this, NoHeaderState, useTransitions); else VisualStateManager.GoToState(this, HasHeaderState, useTransitions) VisualStateManager.GoToState不会使控件重复进入某个状态,譬如如果控件已处于PointerOverState,再次调用VisualStateManager.GoToState(
(this, UnloadedState, true); return; } VisualStateManager.GoToState(this, LoadingState Invoke(this, new ImageExOpenedEventArgs()); VisualStateManager.GoToState(this, LoadedState, true Invoke(this, new ImageExOpenedEventArgs()); VisualStateManager.GoToState(this Invoke(this, new ImageExFailedEventArgs(e)); VisualStateManager.GoToState(this </VisualStateManager.VisualStateGroups> </Grid> </ControlTemplate> </Setter.Value
简单的解决方法就是通过 VisualStateManager 配合 VisualState 来实现 实现效果如下,所有代码都是 XAML 代码 ? Border> </ControlTemplate> </Setter.Value> </Setter> </Style> 接着在 Border 添加 VisualStateManager Border"> <Border.RenderTransform> <ScaleTransform /> </Border.RenderTransform> <VisualStateManager.VisualStateGroups </Border.RenderTransform> <VisualStateManager.VisualStateGroups > </VisualStateGroup> </VisualStateManager.VisualStateGroups
--视觉状态定义区--> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommStates"> <VisualState DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups } private void GoToEnter(object sender, MouseEventArgs e) { VisualStateManager.GoToState , false); } private void GoToLeave(object sender, MouseEventArgs e) { VisualStateManager.GoToState MouseButtonEventArgs e) { rColor.Fill = (sender as Rectangle).Fill; VisualStateManager.GoToState
Name="b" Opacity="0" HorizontalAlignment="Center" Content="显示"></Button> <VisualStateManager.VisualStateGroups </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups Name="b" Opacity="0" HorizontalAlignment="Center" Content="显示"></Button> <VisualStateManager.VisualStateGroups = null) { VisualStateManager.GoToState(litem, "CustomSelected = null) { VisualStateManager.GoToState(litem, "CustomUnselected
Name="b" Opacity="0" HorizontalAlignment="Center" Content="显示"></Button> <VisualStateManager.VisualStateGroups </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups Name="b" Opacity="0" HorizontalAlignment="Center" Content="显示"></Button> <VisualStateManager.VisualStateGroups = null) { VisualStateManager.GoToState(litem, "CustomSelected = null) { VisualStateManager.GoToState(litem, "CustomUnselected
设置按钮背景透明可以通过设置 BackgroundColor 为 Transparent 属性 如果需要让按钮点击时呈现有趣的效果,可以通过 VisualStateManager 的方式定义 BorderColor="Aquamarine" BorderWidth="2"> <VisualStateManager.VisualStateGroups VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups
提供的多个视觉状态,在每个视觉状态下给属性赋值或制作动画 最常用的 VisualStateManager 的 VisualStateGroup 是 CommonStates 组,基础代码组成如下 <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> > 这里有一些细节事项: 由于 VisualStateManager 必须放在容器里面,因此这里必须需要有一个容器控件住 VisualStateManager 的代码。 正常状态需要放在第一个 开始编写正式的代码之前,先复习一下 VisualStateManager 的用法,如下面的代码,既可以在 VisualState 里面使用 Setter 修改属性。 -- 由于 VisualStateManager 必须放在容器里面,因此这里必须需要有一个容器 想省一点的话,可以用 Border 代替 Grid 做容器--> <VisualStateManager.VisualStateGroups
VisualStateManager用于管理UI的视觉状态,可以在UI上设置多个视觉状态,然后用VisualStateManager.GoToState在这些状态间切换,了解自定义控件的开发者对这点应该都不陌生 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups UI,最简单的做法是整个显示/隐藏,例如这样: <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <VisualStateManager.VisualStateGroups </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups
在改变IsExpanded值的同时会依次调用VisualStateManager.GoToState(this, StateContentExpanded, true);、 OnExpanded(EventArgs Expander通过VisualStateManager实现这个功能,做到了UI和代码分离。 (this, StateContentExpanded, false); } else { VisualStateManager.GoToState(this, 所以这里VisualStateManager.GoToState(this, StateContentExpanded, false)的参数useTransitions使用了false。 </VisualStateGroup> </VisualStateManager.VisualStateGroups>
需要平移则加上 TranslateTransform,需要旋转则加上 RotateTransform,并起好名称: 可改变一下数值看看效果: 三、添加转换动画(视觉状态) 在组件布局代码的外面放置 VisualStateManager.VisualStateGroups > 四、使用视觉状态 首先定义一个相应的视觉状态枚举,Key 和之前定义的视觉状态名称相同,方便之后使用: 然后在用户控件后台代码中新增一个依赖属性,用于给外界绑定相应的视觉状态,并在变动方法中使用 VisualStateManager.GoToState 六、关于 VisualStateGroups 的放置位置 以下为正确位置: 如果放在图 1 的 “机械运动区” 的 Canvas 中,则 VisualStateManager.GoToState 方法会返回
Border Width="300" Height="300" Grid.Column="2" Background="DarkCyan"/> </StackPanel> <VisualStateManager.VisualStateGroups view.IsFullScreen && e.NewSize.Width < 500) { VisualStateManager.GoToState (this, "MinimalLayout", true); } else { VisualStateManager.GoToState (this, "DefaultLayout", true); } } 例子中,我们在VisualStateManager中定义了两种视图:DefaultLayout 对VisualStateManager 中视图状态切换的调用发生在 pageRoot_SizeChanged 方法中。
void UpdateVisualState(bool useTransitions = true) { if (_isPointerEntered) VisualStateManager.GoToState (this, PointerOverState, useTransitions); else VisualStateManager.GoToState(this, NormalState, useTransitions); if (Header == null) VisualStateManager.GoToState( this, NoHeaderState, useTransitions); else VisualStateManager.GoToState(this, HasHeaderState
<ControlTemplate TargetType="Thumb"> <Grid> <VisualStateManager.VisualStateGroups Name="Disabled"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups ControlTemplate TargetType="Thumb"> <Grid x:Name="RootGrid"> <VisualStateManager.VisualStateGroups Name="Disabled"/> </VisualStateGroup> </VisualStateManager.VisualStateGroups
控件的代码使用VisualStateManager.GoToState(Control control, string stateName,bool useTransitions)指定控件处于何种VisualState ,控件的ControlTemplate中根节点使用VisualStateManager.VisualStateGroups附加属性,并在其中确定各个VisualState的外观。 TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <VisualStateManager.VisualStateGroups VisualState> <VisualState x:Name="Collapsed" /> </VisualStateGroup> </VisualStateManager.VisualStateGroups ExpansionStates是VisualStateGroup,它包含Expanded和Collapsed两个互斥的状态,控件使用VisualStateManager.GoToState(Control
Window.Current.Bounds.Width 获取窗口高度 Window.Current.Bounds.Height 但是如果我们需要判断我们的窗口大小变化的话,一个简单的方法,使用动态适应 <VisualStateManager.VisualStateGroups </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups
Window.Current.Bounds.Width 获取窗口高度 Window.Current.Bounds.Height 但是如果我们需要判断我们的窗口大小变化的话,一个简单的方法,使用动态适应 <VisualStateManager.VisualStateGroups </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups
TargetType="Button"> <Grid x:Name="Container"> <vsm:VisualStateManager.VisualStateGroups Normal" /> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups > <Grid Background="{TemplateBinding Background}"> <vsm:VisualStateManager.VisualStateGroups Name="Unfocused"/> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups VisualState> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups
添加动画 如果使用了上面的代码可以看到,这个界面按钮是不存在按下的动画,因为没有写 VisualStateManager 现在打开 SormarMapay.xaml 在 AlbumContentGrid 添加下面代码 <VisualStateManager.VisualStateGroups> <VisualStateGroup </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups
看来需要动态地改变,于是必须加上 VisualStateManager。 Grid.Background> <RevealBackgroundBrush /> </Grid.Background> <ContentPresenter /> <VisualStateManager.VisualStateGroups </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups