我想全局禁用我的WPF应用程序中的焦点矩形。对于单个控件可以通过全局禁用FocusVisualStyle
<Style TargetType="Button">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
但如何将它应用到我的应用程序中的所有控件。应用于FrameworkElement时,不会发生任何事情。我需要的是类似于“适用于类x和所有派生类”的东西。
由于提前,
斯特凡
我想全局禁用我的WPF应用程序中的焦点矩形。对于单个控件可以通过全局禁用FocusVisualStyle
<Style TargetType="Button">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
但如何将它应用到我的应用程序中的所有控件。应用于FrameworkElement时,不会发生任何事情。我需要的是类似于“适用于类x和所有派生类”的东西。
由于提前,
斯特凡
这可能不是简单的,但你可以写能改变控制的现有样式的功能。一旦写完了,你可以编写一个函数递归地改变每个元素的样式。
您可以使用OverrideMetadata:
FrameworkElement.FocusVisualStyleProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(null));
我知道这听起来很乏味,但你可能会需要做同样的事情,所有其他控件类型,分别。不过,列出它们并做一些简单的查找/替换操作应该会得到你所需要的。
据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中包含这种风格)。
Window
类的部分缺省Template
是AdornerDecorator
。如果您覆盖Window
的默认Template
不包含AdornerDecorator
,则不会显示所有控件上的FocusVisualStyle
。
即使Control
的有效FocusVisualStyle
设置了Template
,但如果没有AdornerDecorator
,它将不会显示。
一个简单的方法可以将Style
包含在012.x的App.xaml文件中。
<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;
}
}
在我的主窗口的构造然后,我只是叫FocusVisualStyleRemover.Init();
为什么这样做得到-1? – 2009-06-30 02:44:15
可能是因为它不必要地复杂,充满了困难,比如确保你已经覆盖了每一个可能的边缘案例并且很难维护,只是为了命名2.相比于每种类型的“样式”和“设置器”(尽管乏味,简单),你的建议听起来很疯狂。我没有给-1。 – 2009-08-12 21:13:11
由于他没有发表任何解决方案可行的评论,我们不知道其他想法是否有所帮助。如果这是满足他需求的唯一想法,那么“疯狂”将是一个不准确的描述。 – 2009-08-13 14:07:50