Mic*_*eyn 9 c# wpf wpf-controls wpf-4.0 c#-4.0
因此,希望很简单,将按钮的背景更改为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>
Run Code Online (Sandbox Code Playgroud)
但是,唉,这不起作用.我们只是实现目标的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>
...
Run Code Online (Sandbox Code Playgroud)
现在我们已经从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
...
Run Code Online (Sandbox Code Playgroud)
最后,我们取得了进展.我们已经从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>
Run Code Online (Sandbox Code Playgroud)
最后,它按预期工作.
我是疯了,还是这些(以及更多)你必须通过Aero主题来改变一个按钮的背景颜色(正常,悬停,按下)?也许,生活不会那么糟糕,如果我不必在那里包括整个dang ButtonTemplate只是为了从中删除两个属性(RenderMouseOver和RenderPressed).
谢谢你的帮助 - 我结束了.
更新:但等待还有更多.而不是从控件模板中删除RenderMouseOver和RenderPressed属性,只需从以下位置更改它们:
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ...
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}" ...
Run Code Online (Sandbox Code Playgroud)
至:
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ...
RenderMouseOver="{Binding IsMouseOver}"
RenderPressed="{Binding IsPressed}" ...
Run Code Online (Sandbox Code Playgroud)
...,还解决了问题(忽略按钮的样式触发器).我认为问题的根源是模板绑定在编译时应用(出于性能原因),而常规绑定在运行时应用.因此,如果属性使用模板绑定(即,使用原始模板中的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>
Run Code Online (Sandbox Code Playgroud)
这当然假设只有一个按钮是这样设计的,否则模板和样式可以移动到某个地方的资源部分.此外,没有按钮的默认状态触发器,但它很容易添加到上面的示例中(不要忘记更改控件模板中的RenderDefaulted属性以使用Binding而不是TemplateBinding).
如果有人对如何使用Binding 覆盖 TemplateBinding只有控件模板中需要更改的两个属性的任何建议,而不重复aero xaml批发的整个chrome定义,我很满意.
默认模板Button使用ButtonChrome,它执行自己的绘图。如果您想完全摆脱默认外观,您需要定义自己的模板,而不需要ButtonChrome. 我知道这听起来很乏味,但您只需要做一次:您可以将自定义样式放入资源字典中,然后使用StaticResource. {x:Type Button}请注意,您还可以通过使用样式的键(x:Key属性)将样式应用于应用程序中的所有按钮