Deactivate FocusVisualStyle globally

走远了吗. 提交于 2019-12-18 12:13:29

问题


I want to globally deactivate the focus rectangles in my WPF application. For single controls that can be done via

<Style TargetType="Button">
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>

but how to apply it to all controls in my application. When applying to FrameworkElement nothing happens. What I need would be something like "apply to class x and all derived classes".

Thanks in advance,

Stefan


回答1:


Looks like there's no magic bullet for this:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/141c8bfa-f152-4f8a-aca0-3c3b5440d183




回答2:


According to http://msdn.microsoft.com/en-us/library/bb613567.aspx, you should be able to set global focus style like this:

<Style x:Key="{x:Static SystemParameters.FocusVisualStyleKey}">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate>
        <Rectangle StrokeThickness="1"
          Stroke="Black"
          StrokeDashArray="1 2"
          SnapsToDevicePixels="true"/>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style> 

I haven't tested it, but I guess that when you empty the controltemplate, this would effectively disable the focus rectangle for the whole app (provided you include this style in app.xaml).




回答3:


I stumbled upon this as well and came up with this (indeed not very nice but effective) solution:

public class FocusVisualStyleRemover
{
  static FocusVisualStyleRemover()
  {
    EventManager.RegisterClassHandler(typeof(FrameworkElement), FrameworkElement.GotFocusEvent, new RoutedEventHandler(RemoveFocusVisualStyle), true);
  }

  public static void Init()
  {
    // intentially empty
  }

  private static void RemoveFocusVisualStyle(object sender, RoutedEventArgs e)
  {
    (sender as FrameworkElement).FocusVisualStyle = null;
  }
}

In my MainWindow's constructor I then just call FocusVisualStyleRemover.Init();




回答4:


I know it sounds tedious, but you'll probably have to do the same thing for all the other control types, individually. Making a list of them and doing a couple simple Find/Replace operations should get you what you need, though.




回答5:


This may not be simple, but you could write a function that alters the existing style of a control. Once that is written, you could write a function that recursively alters the style of each element.




回答6:


You can use OverrideMetadata:

FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
    typeof(FrameworkElement),
    new FrameworkPropertyMetadata(null));
  1. you have to call this before any element is created, the Application.Startup event is probably the best place.
  2. This will only effect controls that use FrameworkElement's focus visual style and will not change controls that override it in code or styles.
  3. I haven't tries doing this with FocusVisualStyle myself



回答7:


Part of the default Template for the Window class is an AdornerDecorator. If you override the Window's default Template to not include an AdornerDecorator, the FocusVisualStyle on all controls will not appear.

Even if a Control has a valid FocusVisualStyle that sets a Template, it will not appear without the AdornerDecorator.

An easy way to accomplish this is to include this Style in your App.xaml file under Application.Resources.

<Style TargetType="{x:Type Window}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                    <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="ResizeMode" Value="CanResizeWithGrip">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Window}">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                            <Grid>
                                <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
                                <ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" IsTabStop="False" Visibility="Collapsed" VerticalAlignment="Bottom"/>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="ResizeMode" Value="CanResizeWithGrip"/>
                                    <Condition Property="WindowState" Value="Normal"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/>
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>


来源:https://stackoverflow.com/questions/1055670/deactivate-focusvisualstyle-globally

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!