c# - trigger - wpf styles templates
Desactivar FocusVisualStyle globalmente (7)
Quiero desactivar globalmente los rectángulos de enfoque en mi aplicación WPF. Para controles individuales que se pueden hacer a través de
<Style TargetType="Button">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
pero cómo aplicarlo a todos los controles en mi aplicación. Cuando se aplica a FrameworkElement no pasa nada. Lo que necesito sería algo como "aplicar a la clase x y todas las clases derivadas".
Gracias por adelantado,
Stefan
De acuerdo con http://msdn.microsoft.com/en-us/library/bb613567.aspx , debería poder establecer un estilo de enfoque global como este:
<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>
No lo he probado, pero supongo que cuando vacíe la plantilla de control, esto deshabilitará de manera efectiva el rectángulo de enfoque para toda la aplicación (siempre que incluya este estilo en app.xaml).
Me topé con esto también y se me ocurrió esta solución (de hecho no muy agradable pero efectiva):
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;
}
}
En el constructor de mi MainWindow, llamé a FocusVisualStyleRemover.Init();
Parece que no hay una bala mágica para esto:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/141c8bfa-f152-4f8a-aca0-3c3b5440d183
Parte de la Template
predeterminada para la clase de Window
es un AdornerDecorator
. Si reemplaza la Template
predeterminada de la Window
para no incluir un AdornerDecorator
, no aparecerá el FocusVisualStyle
de FocusVisualStyle
de FocusVisualStyle
en todos los controles.
Incluso si un Control
tiene un FocusVisualStyle
válido que establece una Template
, no aparecerá sin el AdornerDecorator
.
Una forma fácil de lograr esto es incluir este Style
en su archivo App.xaml bajo 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>
Puede que esto no sea simple, pero podría escribir una función que altere el estilo existente de un control. Una vez que se haya escrito, podría escribir una función que altere recursivamente el estilo de cada elemento.
Puedes usar OverrideMetadata:
FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(null));
- Debe llamar a esto antes de crear cualquier elemento, el evento Application.Startup es probablemente el mejor lugar.
- Esto solo afectará a los controles que usen el estilo visual de enfoque de FrameworkElement y no cambiará los controles que lo anulan en el código o los estilos.
- No he intentado hacer esto con FocusVisualStyle
Sé que suena tedioso, pero probablemente tendrás que hacer lo mismo para todos los demás tipos de control, individualmente. Sin embargo, hacer una lista de ellos y hacer un par de simples operaciones de Buscar / Reemplazar debería obtener lo que necesita.