Reputation: 203
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
Upvotes: 20
Views: 11867
Reputation: 240
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();
Upvotes: 3
Reputation: 872
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>
Upvotes: 0
Reputation: 4833
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).
Upvotes: 4
Reputation: 2749
Looks like there's no magic bullet for this:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/141c8bfa-f152-4f8a-aca0-3c3b5440d183
Upvotes: 4
Reputation: 24766
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.
Upvotes: 1
Reputation: 29594
You can use OverrideMetadata:
FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(null));
Upvotes: -1
Reputation: 22717
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.
Upvotes: 0