VisualStateManager状态切换失效:自定义标题栏按钮Hover无响应
问题排查与修复方案
核心问题1:VisualStateManager放置位置错误
你的VisualStateManager.VisualStateGroups被嵌套在<Border>内部,正确的做法是将其直接放在ControlTemplate的**根元素(RootGrid)**下方——VisualStateManager需要绑定到模板的根容器,才能正确管理整个控件的状态切换。
核心问题2:VisualState Setter的Target路径错误
Border控件的x:Name是border,但你在VisualState的Setter里写的是Border.Background(这里的Border是控件类型名,不是实例名),应该改为border.Background,指向模板中具体的Border实例。
额外优化:无需手动监听Pointer事件(可选)
如果MyTitleBarButton继承自WPF/UWP的Button控件,默认已经内置了CommonStates的状态切换逻辑,不需要手动编写PointerEntered和PointerExited事件处理代码,移除这些绑定后就能自动触发状态切换。
修复后的完整代码
修正后的ControlTemplate
<!--ButtonTrigger für den Minimize-Button--> <ControlTemplate TargetType="myCoreCrl:MyTitleBarButton" x:Key="ControlTemplateForMinimized"> <Grid x:Name="RootGrid"> <!-- 将VisualStateManager移到根Grid下 --> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"> <VisualState.Setters> <!-- 修正Target为控件实例名border --> <Setter Target="border.Background" Value="{StaticResource NoColor}"/> </VisualState.Setters> </VisualState> <VisualState x:Name="PointerOver"> <VisualState.Setters> <Setter Target="border.Background" Value="{StaticResource MouseOver}"/> </VisualState.Setters> </VisualState> <VisualState x:Name="Disabled"> <VisualState.Setters> <Setter Target="border.Visibility" Value="Collapsed"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"> <ContentPresenter x:Name="presenter" Content="" FontFamily="Segoe MDL2 Assets" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> </Grid> </ControlTemplate>
(可选)移除手动事件绑定
若使用控件默认状态逻辑,修改Button的XAML,去掉Pointer事件绑定:
<!--Button zum Minimizen--> <myCoreCrl:MyTitleBarButton x:Name="ButtonMinimize" Grid.Row="0" Grid.Column="1" Style="{StaticResource HeaderButtonStyle}" Template="{StaticResource ControlTemplateForMinimized}" Click="BtnMinimize"/>
同时移除后台的事件处理代码:
// 删除以下代码块 private void PointerEntered(object sender, PointerRoutedEventArgs args) { Trace.WriteLine("PointerOver"); VisualStateManager.GoToState((MyTitleBarButton)sender, "PointerOver", true); } private void PointerExited(object sender, PointerRoutedEventArgs args) { Trace.WriteLine("Normal"); VisualStateManager.GoToState((MyTitleBarButton)sender, "Normal", true); }
内容的提问来源于stack exchange,提问作者Pain Nncera
相关产品推荐
相关产品推荐

