Ответ 1
Похоже, нет волшебной пули для этого:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/141c8bfa-f152-4f8a-aca0-3c3b5440d183
Я хочу глобально деактивировать прямоугольники фокуса в моем приложении WPF. Для отдельных элементов управления, которые можно выполнить с помощью
<Style TargetType="Button">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
но как применить его ко всем элементам управления в моем приложении. При применении к FrameworkElement ничего не происходит. Мне нужно было бы что-то вроде "применить к классу x и всем производным классам".
Спасибо заранее,
Стефан
Похоже, нет волшебной пули для этого:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/141c8bfa-f152-4f8a-aca0-3c3b5440d183
Согласно 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).
Я знаю, это звучит утомительно, но вам, вероятно, придется делать то же самое для всех других типов управления, в отдельности. Создание списка из них и выполнение нескольких простых операций Find/Replace должно помочь вам в том, что вам нужно.
Это может быть не просто, но вы можете написать функцию, которая изменяет существующий стиль элемента управления. Как только это будет написано, вы можете написать функцию, которая рекурсивно изменяет стиль каждого элемента.
Вы можете использовать OverrideMetadata:
FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(null));
Часть стандартного 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>
Я тоже наткнулся на это и придумал это (действительно, не очень приятное, но эффективное) решение:
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();