C# 全局停用 FocusVisualStyle

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1055670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 07:07:57  来源:igfitidea点击:

Deactivate FocusVisualStyle globally

c#wpfstyles

提问by grayscales

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

我想在我的 WPF 应用程序中全局停用焦点矩形。对于可以通过以下方式完成的单个控件

<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".

但是如何将其应用于我的应用程序中的所有控件。当应用到 FrameworkElement 时,什么也没有发生。我需要的是“适用于类 x 和所有派生类”。

Thanks in advance,

提前致谢,

Stefan

斯特凡

回答by John Fisher

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.

这可能并不简单,但您可以编写一个函数来改变控件的现有样式。一旦编写完成,您就可以编写一个函数来递归地改变每个元素的样式。

回答by Nir

You can use OverrideMetadata:

您可以使用 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
  1. 您必须在创建任何元素之前调用它,Application.Startup 事件可能是最好的地方。
  2. 这只会影响使用 FrameworkElement 的焦点视觉样式的控件,并且不会更改在代码或样式中覆盖它的控件。
  3. 我自己还没有尝试过用 FocusVisualStyle 做到这一点

回答by Joel B Fant

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.

我知道这听起来很乏味,但您可能必须对所有其他控件类型分别执行相同的操作。不过,列出它们并执行一些简单的查找/替换操作应该可以满足您的需求。

回答by Tomá? Kafka

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

根据http://msdn.microsoft.com/en-us/library/bb613567.aspx,您应该能够像这样设置全局焦点样式:

<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).

我还没有测试过,但我想当您清空 controltemplate 时,这将有效地禁用整个应用程序的焦点矩形(前提是您在 app.xaml 中包含此样式)。

回答by Tim Cooke

Part of the default Templatefor the Windowclass is an AdornerDecorator. If you override the Window's default Templateto not include an AdornerDecorator, the FocusVisualStyleon all controls will not appear.

默认的部分TemplateWindow类是一个AdornerDecorator。如果您将Window的默认值覆盖Template为不包括AdornerDecorator,则FocusVisualStyle所有控件上的 都不会出现。

Even if a Controlhas a valid FocusVisualStylethat sets a Template, it will not appear without the AdornerDecorator.

即使 aControl具有FocusVisualStyle设置 a的有效值Template,它也不会在没有 的情况下出现AdornerDecorator

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

完成此操作的一种简单方法是将其包含Style在 .app 下的 App.xaml 文件中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>

回答by Tromse

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();

在我的 MainWindow 的构造函数中,我只需调用 FocusVisualStyleRemover.Init();