gpt4 book ai didi

c# - 在 Aero 上的 WPF 中覆盖按钮背景

转载 作者:太空狗 更新时间:2023-10-29 17:58:41 25 4
gpt4 key购买 nike

因此,愿望很简单,将按钮的背景更改为 LightGreen,鼠标光标悬停在其上时为绿色,按下时为 DarkGreen。以下 XAML 是我的第一次尝试:

<Window x:Class="ButtonMouseOver.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Background="LightGreen">
Hello
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property = "Background" Value="Green"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property = "Foreground" Value="DarkGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>

但是,唉,这是行不通的。我们只完成了目标的 1/3。是的,该按钮变为浅绿色,但只要将鼠标悬停在它上面或按下它,您就会获得相应按钮状态的标准 Aero chrome。不想放弃,我尝试以下放荡:

...
<Button xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Background="LightGreen">
Hello
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true"
x:Name="Chrome" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding IsDefaulted}"
RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"
>
<ContentPresenter Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>
</Button.Template>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property = "Background" Value="Green"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property = "Foreground" Value="DarkGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
...

现在我们已经从 Aero.NormalColor.xaml 中提取了整个该死的控件模板。 las,这没有任何改变。然后,我开始从 Microsoft_Windows_Themes:ButtonChrome 元素中删除两个属性(RenderPressedRenderMouseOver)。尽管如此,还是没有变化。然后,我删除了 Button 的 Background 属性的设置,只留下 PresentationFramework.Aero 程序集的 namespace 声明:

...
<Button xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
Hello
...

终于,我们取得了进展。我们已经从 1/3 的要求减少到 2/3 的方式,IsMouseOver 和 IsPressed 工作,但在按钮的正常状态(没有被鼠标悬停或按下)期间没有浅绿色背景,因为我已经删除按钮的 Background 属性,以获取其他两个状态应用并可见。现在,在这个疯狂的 XAML 未能为我们提供正常按钮状态的 LightGreen 背景之后,我修改了样式以将背景颜色也扔进去:

  <Button xmlns...
<ControlTemplate...
...
</ControlTemplate>
<Button.Style>
<Style TargetType="Button">
<!-- ##### Normal state button background added ##### -->
<Setter Property="Background" Value="LightGreen" />
<!-- ################################################ -->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property = "Background" Value="Green"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property = "Background" Value="DarkGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

最后,它按预期工作。

我是不是疯了,或者这些(以及更多)你必须通过 Aero 主题才能改变按钮在其各种状态(正常、悬停、按下)下的背景颜色?也许,如果我不必在其中包含整个该死的 ButtonTemplate 只是为了从中删除两个属性(RenderMouseOverRenderPressed),生活就不会那么糟糕.

感谢您的帮助 - 我已经无能为力了。

更新:但等等还有更多。无需从控件模板中删除 RenderMouseOver 和 RenderPressed 属性,只需将它们更改为:

<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ...
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}" ...

到:

<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ...
RenderMouseOver="{Binding IsMouseOver}"
RenderPressed="{Binding IsPressed}" ...

...,还解决了问题(忽略按钮的样式触发器)。我认为问题的根源在于模板绑定(bind)是在编译时应用的(出于性能原因),而常规绑定(bind)是在运行时应用的。因此,如果属性使用模板绑定(bind)(即使用原始模板中的 IsMouseOver 和 IsPressed),则不会使用来自单个按钮的样式触发器的绑定(bind)。

综上所述,下面是在 Aero 中更改按钮背景同时保留其原始控件模板的典型示例:

<Window x:Class="ButtonMouseOver.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button>
Hello
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true"
x:Name="Chrome" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding IsDefaulted}"
RenderMouseOver="{Binding IsMouseOver}" RenderPressed="{Binding IsPressed}"
>
<ContentPresenter Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>
</Button.Template>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="LightGreen"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property = "Background" Value="Green"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property = "Foreground" Value="DarkGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>

这当然是假设只有一个按钮是这样设计的,否则模板和样式可以移出到某处的资源部分。此外,按钮的默认状态没有触发器,但它很容易添加到上面的示例中(不要忘记更改控件模板中的 RenderDefaulted 属性以使用 Binding 而不是 TemplateBinding)。

如果有人对如何仅针对需要更改的控件模板中的两个属性覆盖具有绑定(bind)的 TemplateBinding 有任何建议,而无需重复 aero xaml 批发中的整个 chrome 定义,我我洗耳恭听。

最佳答案

Button 的默认模板使用 ButtonChrome,它执行自己的绘图。如果你想完全摆脱默认外观,你需要定义你自己的模板,没有 ButtonChrome。我知道这听起来很乏味,但您只需要做一次:您可以将自定义样式放入资源字典中,然后使用 StaticResource 引用它。请注意,您还可以通过使用 {x:Type Button} 作为样式的键(x:Key 属性)

将样式应用于应用中的所有按钮

关于c# - 在 Aero 上的 WPF 中覆盖按钮背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4424699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com