WPF 禁用按钮的背景
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25406878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Disabled button's background
提问by Junior222
I try to change button's style when it is disabled:
我尝试在禁用按钮时更改按钮的样式:
<Style TargetType="Button" x:Key="MyButton2">
<Setter Property="Background" Value="MediumAquamarine" />
<Setter Property="Foreground" Value="MediumBlue" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" Value="Green"/>
<Setter Property="Foreground" Value="DeepPink"/>
</Trigger>
</Style.Triggers>
</Style>
and my button:
和我的按钮:
<Button Style="{StaticResource MyButton2}" Content="My text" Width="100" Height="30" IsEnabled="False" />
But for some reason This style is not applied to the button:
但由于某种原因,这种样式不适用于按钮:
How can i apply this style to my button? And can i do it without overriding button's template only with styles?
我如何将这种样式应用到我的按钮上?我可以在不覆盖按钮模板的情况下只使用样式吗?
回答by Anatoliy Nikolaev
Can I do it without overriding button's template only with styles?
我可以在不覆盖按钮模板的情况下仅使用样式吗?
I think not, because the Controls in the Windows has a default Styles
and ControlTemplates
and in each version of Windows they are different. In addition, the styles - it's just a lot of settings, usually the style does not change/add behavior to control, which is responsible for this ControlTemplate
.
我认为不是,因为 Windows 中的控件有一个默认值Styles
,ControlTemplates
并且在每个版本的 Windows 中它们都是不同的。此外,样式 - 它只是很多设置,通常样式不会更改/添加要控制的行为,这是为此负责的ControlTemplate
。
Note:
the Style it is a set of setters, for example: set the background, size, etc. The ControlTemplate
is the form, in which all of these settings will appear.
Note:
Style 它是一组setter,例如:设置背景、大小等。the ControlTemplate
is the form,所有这些设置都会在其中出现。
In this situation, I recommend you all to change the ControlTemplate, where it is possible to have the same behavior aka view, regardless of the version of the system.
在这种情况下,我建议大家更改 ControlTemplate,无论系统版本如何,都可能具有相同的行为,即视图。
In this case, try this Style
:
在这种情况下,试试这个Style
:
<Window.Resources>
<Style TargetType="Button" x:Key="MyButton2">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Background" Value="MediumAquamarine" />
<Setter Property="Foreground" Value="MediumBlue" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter x:Name="MyContentPresenter"
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Green"/>
<Setter Property="Foreground" Value="DeepPink"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Button Content="Button"
IsEnabled="False"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="75"
Style="{StaticResource MyButton2}"
Click="Button_Click"/>
</Grid>
回答by Stígandr
The odd thing is that it "works" when i run it, well partly, and this is likely to the template of the button actually. Here is a buttons entire template.
奇怪的是,当我运行它时它“有效”,部分原因,这实际上可能是按钮的模板。这是一个按钮整个模板。
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
As you can see there is alot of things going on in the control template of the button. In example the following SolidColorBrushes are used when the ctl is disabled.
正如您所看到的,按钮的控件模板中发生了很多事情。在示例中,当禁用 ctl 时使用以下 SolidColorBrushes。
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
You can either change these (in scope of your usercontrol, app), or you can rewrite the control template as Suggested by Daniel Ward.
您可以更改这些(在您的用户控件、应用程序范围内),也可以按照 Daniel Ward 的建议重写控件模板。
You may dump the default template of any control by right clicking it in the UI Editor, Edit Template -> Create a copy... Through blend, code or disassembling :)
您可以通过在 UI 编辑器中右键单击任何控件的默认模板,编辑模板 -> 创建副本...通过混合、编码或反汇编来转储任何控件的默认模板:)
Hope it helps!
希望能帮助到你!
Cheers
干杯
Stian
斯蒂安
回答by Mohammed Larabi
My solution is a bit easier but it does not allow to use a Transparent
background color for a disabled button and you cannot change the BorderBrush
either.
What I do is using a TextBlock
as a content of the button and change the color of this TextBlock
background when it's disabled.
我的解决方案更简单一些,但它不允许Transparent
为禁用的按钮使用背景颜色,您也不能更改BorderBrush
。我所做的是使用 aTextBlock
作为按钮的内容,并在TextBlock
禁用时更改此背景的颜色。
My button is written like this:
我的按钮是这样写的:
<Button>
<TextBlock Text="Click me!" Style="{StaticResource MyButtonContentStyle}" />
</Button>
And MyButtonContentStyle is written like this:
而 MyButtonContentStyle 是这样写的:
<Style x:Key="MyButtonContentStyle" TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
It worked like a charm for us.
它对我们来说就像一种魅力。
回答by Ishan Khanna
Might be late on this one but there is an in built property provided by WPF:
可能会迟到,但 WPF 提供了一个内置属性:
IsHitTestVisible="False"
IsHitTestVisible="False"
Any kind of mouse movement is not detectable using the above on a control thus disabling a control without changing its actual look and feel.
使用上述控件无法检测到任何类型的鼠标移动,从而禁用控件而不改变其实际外观和感觉。
回答by Daniel Ward
It seems that the only way to do this is to remove the chrome theme from the button. Note that this will remove the hovering/clicking animations, as well as the button's gradient on Windows 7, if you're building for that.
似乎唯一的方法是从按钮中删除 chrome 主题。请注意,这将删除悬停/点击动画,以及 Windows 7 上按钮的渐变(如果您正在为此构建)。
Unfortunately, Microsoft decided that disabling a button should give the background a hardcoded value from a private property in the chrome theme's code-behind, which means that you can't change it through the XAML. That link describes the problem:
不幸的是,Microsoft 决定禁用按钮应该从 chrome 主题的代码隐藏中的私有属性中为背景提供一个硬编码值,这意味着您无法通过 XAML 更改它。该链接描述了问题:
The control template for Button
uses ButtonChrome
, which has a private property called ButtonOverlay
, which, when the Button
has IsEnabled
set to False
, sets the Background
to new SolidColorBrush(Color.FromRgb(0xf4, 0xf4, 0xf4))
(or RGB 244,244,244), which is the grey you see. You can't change that.
对于控制模板Button
的用途ButtonChrome
,其中有一个叫做私有财产ButtonOverlay
,其中,在Button
已IsEnabled
设置为False
,设置Background
到new SolidColorBrush(Color.FromRgb(0xf4, 0xf4, 0xf4))
(或RGB 244244244),这是你看到的灰色。你不能改变这一点。
What you can do is create a new control template for the button (yay), replacing the Themes:ButtonChrome
element with a Border
element, which you are able to change the Background
of.
您可以做的是为按钮 (yay) 创建一个新的控件模板,用您可以更改的元素替换该Themes:ButtonChrome
元素。Border
Background
It may not appear to work in design view, but it works when you run it.
它可能在设计视图中似乎不起作用,但在您运行它时却起作用。
So, for instance, for yours, it might look something like:
因此,例如,对于您来说,它可能看起来像:
<!-- Default button focus visual -->
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="MediumAquamarine"/>
<Setter Property="Foreground" Value="MediumBlue"/>
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="DeepPink"/>
<Setter Property="Background" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>