Подтвердить что ты не робот

Деактивировать FocusVisualStyle глобально

Я хочу глобально деактивировать прямоугольники фокуса в моем приложении WPF. Для отдельных элементов управления, которые можно выполнить с помощью

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

но как применить его ко всем элементам управления в моем приложении. При применении к FrameworkElement ничего не происходит. Мне нужно было бы что-то вроде "применить к классу x и всем производным классам".

Спасибо заранее,

Стефан

4b9b3361

Ответ 2

Согласно 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> 

Я не тестировал его, но я предполагаю, что когда вы очистите контрольную таблицу, это фактически отключит прямоугольник фокуса для всего приложения (если вы включите этот стиль в app.xaml).

Ответ 3

Я знаю, это звучит утомительно, но вам, вероятно, придется делать то же самое для всех других типов управления, в отдельности. Создание списка из них и выполнение нескольких простых операций Find/Replace должно помочь вам в том, что вам нужно.

Ответ 4

Это может быть не просто, но вы можете написать функцию, которая изменяет существующий стиль элемента управления. Как только это будет написано, вы можете написать функцию, которая рекурсивно изменяет стиль каждого элемента.

Ответ 5

Вы можете использовать OverrideMetadata:

FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
    typeof(FrameworkElement),
    new FrameworkPropertyMetadata(null));
  • вы должны вызвать это, прежде чем какой-либо элемент будет создан, событие Application.Startup, вероятно, лучшее место.
  • Это будет влиять только на элементы управления, которые используют визуальный стиль FocusElement, и не изменят элементы управления, которые переопределяют его в коде или стилях.
  • Я не пытаюсь сделать это с самим FocusVisualStyle.

Ответ 6

Часть стандартного Template для класса Window - AdornerDecorator. Если вы переопределите Window по умолчанию Template, чтобы не включать AdornerDecorator, FocusVisualStyle для всех элементов управления не будет отображаться.

Даже если a Control имеет действительный FocusVisualStyle, который устанавливает a Template, он не будет отображаться без AdornerDecorator.

Простым способом для этого является включение этого Style в ваш файл 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>

Ответ 7

Я тоже наткнулся на это и придумал это (действительно, не очень приятное, но эффективное) решение:

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;
  }
}

В моем конструкторе MainWindow я просто вызываю FocusVisualStyleRemover.Init();