所以,希望很简单,将按钮的背景更改为LightGreen,将鼠标光标悬停在其上时为绿色,按下时将DarkGreen更改为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镀铬。不想放弃,我尝试以下放荡:
...
<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 中取出了整个friggin'控制模板。唉,这没什么改变。然后,我将从RenderPressed
元素中删除两个属性(RenderMouseOver
和Microsoft_Windows_Themes:ButtonChrome
)。不过,没有变化。然后我删除Button的Background
属性的设置,只留下PresentationFramework.Aero程序集的名称空间声明:
...
<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主题来改变按钮的背景颜色,只是在一些不同的状态(正常,悬停,按下)?也许,如果我不必在其中包含整个Button Button,只是为了从中移除两个属性(RenderMouseOver
和RenderPressed
),生活就不会那么糟糕。
感谢您的帮助 - 我结束了。
更新:但等待还有更多内容。而不是从控件模板中删除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}" ...
...,也修复了问题(忽略了按钮的样式触发器)。我认为问题的根源是模板绑定在编译时应用(出于性能原因),而常规绑定在运行时应用。因此,如果属性使用模板绑定(即,使用原始模板中的IsMouseOver和IsPressed),则不使用来自单个按钮的样式触发器的绑定。
说完上述所有内容后,这里是在保留原始控件模板的同时更改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)。
如果有任何人对如何覆盖有关Binding的TemplateBinding只有控件模板中需要更改的两个属性有任何建议,而不重复aero xaml批发的整个Chrome定义,我我都是耳朵。
答案 0 :(得分:2)
Button
的默认模板使用ButtonChrome
,执行自己的绘图。如果您想完全摆脱默认外观,则需要定义自己的模板,而不需要ButtonChrome
。我知道这听起来很乏味,但您只需要执行一次:您可以将自定义样式放在资源字典中,然后使用StaticResource
引用它。请注意,您还可以使用{x:Type Button}
作为样式的键(x:Key
属性)将样式应用于应用中的所有按钮