压倒一切的按钮背景在WPF上的Aero [英] Overriding button background in WPF on Aero

查看:158
本文介绍了压倒一切的按钮背景在WPF上的Aero的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此​​,愿望很简单,当被按下时,鼠标光标悬停和深绿更改按钮的背景浅绿,绿。下面的XAML是我第一次尝试:

So, the desire is simple, change a button's background to LightGreen, Green when the mouse cursor hovers over it and DarkGreen when it is pressed. The following XAML is my first attempt:

<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镶边各自的按钮状态。不想放弃,我尝试下面的放荡:

But, alas this doesn't work. We're only 1/3 of the way towards the goal. Yes, the button becomes light green, but as soon as you hover over it or press it you get standard Aero chrome for the respective button states. Not wanting to give up, I attempt the following debauchery:

...
    <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 解除。唉,这改变不了什么。然后我去删除两个属性( RenderPressed RenderMouseOver )从 Microsoft_Windows_Themes:ButtonChrome 元素。尽管如此,没有变化。然后,我删除的按钮的背景属性的设置,只留下空间声明为PresentationFramework.Aero装配:

Now we've got the whole friggin' control template thrown in there lifted from Aero.NormalColor.xaml. Alas, this changes nothing. I then go about removing two attributes (RenderPressed and RenderMouseOver) from the Microsoft_Windows_Themes:ButtonChrome element. Still, there is no change. I then remove the setting of the Button's Background attribute, leaving just the namespace declaration for the PresentationFramework.Aero assembly:

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



最后,我们有进步。我们从要求的1/3去的方式2/3,与IsMouseOver和IsPressed工作,但按钮的正常状态时无浅绿色背景(不被滑鼠移到或按下),因为我已经删除从按钮背景财产,得到其他两个州申请,并可见。现在,经过这疯狂的XAML未能得到我们正常按钮状态的浅绿的背景下,我修改样式扔背景颜色在那里还有:

Finally, we have progress. We've gone from 1/3 of the requirements to 2/3 of the way, with IsMouseOver and IsPressed working, but no light green background during the button's normal state (of not being moused over or pressed), since I've removed the Background property from the button, to get the other two states to apply and be visible. Now, after this maniacal XAML fails to get us the LightGreen background for the normal button state, I modify the style to throw the background color in there as well:

  <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>



最后,按预期工作。

Finally, it works as intended.

我疯了,或者是这些(及以上),你必须去通过与Aero主题,只是改变一个按钮的背景颜色在某些各种状态的箍(正常,悬停,按下)?也许,生活会不会如此糟糕,如果我没有包括整个宕ButtonTemplate在那里只是卸下两个属性( RenderMouseOver RenderPressed )从它

Am I crazy, or are these (and more) the hoops you have to go through with an Aero theme to just change a button's background color in some of its various states (normal, hovered over, pressed)? Maybe, life wouldn't be so bad if I didn't have to include the whole dang ButtonTemplate in there just to remove the two attributes (RenderMouseOver and RenderPressed) from it.

感谢您的帮助 - 我在束手无策

Thank you for any help - I am at wit's end.

更新:别急还有更多的这一点。除删除RenderMouseOver和RenderPressed从控制模板属性,只需更改它们:

Update: But wait there's more to this. Instead of removing the RenderMouseOver and RenderPressed attributes from the control template, simply changing them from:

<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)不使用触发器。

..., also fixes the problem (of ignoring the button's style triggers). I think the root of the issue is that the template bindings are applied at compile time (for performance reasons), while regular bindings are applied at run time. Because of this, the bindings from the style triggers from the individual buttons are not used if attributes use template bindings (i.e., the IsMouseOver and IsPressed from the original template are used instead).

说了上面的,下面是在航空更改按钮的背景,同时保持其原有的控制模板中的典型的例子:

Having said all of the above, here is the canonical example for changing a button's background in Aero while keeping its original control template:

<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属性使用绑定,而不是TemplateBinding)。

This is of course assuming that only one button is so styled, otherwise the template and style can be moved out into a resources section somewhere. Also, there is no trigger for the default state of a button, but it is easily added to the above example (don't forget to change the RenderDefaulted attribute in the control template to use Binding instead of TemplateBinding).

如果任何人有任何建议,如何替换与绑定只在需要改变控制模板中的两个属性,但不重复整个镀铬定义TemplateBinding从航空XAML批发,我所有的耳朵。

If anyone has any suggestions on how to override the TemplateBinding with Binding for only the two attributes in the control template that need to change, without repeating the entire chrome definition from the aero xaml wholesale, I am all ears.

推荐答案

按钮默认的模板使用 ButtonChrome ,它执行自己的绘画。如果你想完全摆脱默认外观,你需要定义自己的模板,而不 ButtonChrome 。我知道这听起​​来很乏味,但你只需要做一次:你可以把一个资源字典你的自定义样式,只是指它与静态资源。请注意,您还可以使用应用样式到应用中的所有按钮 {X:类型按钮} 作为样式的按键( X:键属性)

The default template for Button uses a ButtonChrome, which performs its own drawing. If you want to get completely rid of the default appearance, you need to define your own template, without the ButtonChrome. I know it sounds tedious, but you only have to do it once: you can put your custom style in a resource dictionary, and just refer to it with StaticResource. Note that you can also apply the style to all buttons in your app by using {x:Type Button} as the style's key (x:Key attribute)

这篇关于压倒一切的按钮背景在WPF上的Aero的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆