【问题标题】:Why is the Button's Background changing?为什么按钮的背景会发生变化?
【发布时间】:2009-08-19 21:35:54
【问题描述】:

我是 WPF 的初学者,我什至不知道在哪里可以找到这个问题的答案。这个 XAML 对我来说似乎很简单:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>
    <Button>
      <Button.Style>
        <Style TargetType="{x:Type Button}">
        <Style.Triggers>
          <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="Green"/>
          </Trigger>      
        </Style.Triggers>
        </Style>
      </Button.Style>
      <Button.Content>Test</Button.Content>
    </Button>
  </Grid>
</Page>

当我将鼠标悬停在按钮上时,IsMouseOver 变为True,并且触发器使背景变为绿色。一瞬间。然后变成蓝色。

更好的是:如果我将相同的设置器附加到 IsFocused 属性,一旦我关注按钮,背景颜色就会在绿色和蓝色之间跳动。

在 Button 的某个地方(我猜它是在 Vista 下使用的任何默认主题中)有一些东西使它以这种方式运行。我怀疑触发器需要设置另一个属性。但是什么?

【问题讨论】:

    标签: wpf button triggers styles


    【解决方案1】:

    您需要更改ButtonTemplate 而不是Style。模板中内置了一个名为ButtonChrome 的东西,这就是导致恼人的蓝色焦点效果的原因。下面是 Button 控件的一个非常简单的重新模板化,取自提供的简单样式:

    <Style TargetType="{x:Type Button}">
       <Setter Property="SnapsToDevicePixels" Value="true"/>
       <Setter Property="OverridesDefaultStyle" Value="true"/>
       <Setter Property="MinHeight" Value="23"/>
       <Setter Property="MinWidth" Value="75"/>
       <Setter Property="Template">
         <Setter.Value>
           <ControlTemplate TargetType="{x:Type Button}">
             <Border 
               x:Name="Border"  
               CornerRadius="2" 
               BorderThickness="1"
               Background="#C0C0C0"
               BorderBrush="#404040">
               <ContentPresenter 
                 Margin="2"
                 HorizontalAlignment="Center"
                 VerticalAlignment="Center"
                 RecognizesAccessKey="True"/>
             </Border>
             <ControlTemplate.Triggers>
               <Trigger Property="IsKeyboardFocused" Value="true">
                 <Setter TargetName="Border" Property="BorderBrush" Value="#202020" />
               </Trigger>
               <Trigger Property="IsDefaulted" Value="true">
                 <Setter TargetName="Border" Property="BorderBrush" Value="#202020" />
               </Trigger>
               <Trigger Property="IsMouseOver" Value="true">
                 <Setter TargetName="Border" Property="Background" Value="#808080" />
               </Trigger>
               <Trigger Property="IsPressed" Value="true">
                 <Setter TargetName="Border" Property="Background" Value="#E0E0E0" />
                 <Setter TargetName="Border" Property="BorderBrush" Value="#606060" />
               </Trigger>
               <Trigger Property="IsEnabled" Value="false">
                 <Setter TargetName="Border" Property="Background" Value="#EEEEEE" />
                 <Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
                 <Setter Property="Foreground" Value="#888888"/>
               </Trigger>
             </ControlTemplate.Triggers>
           </ControlTemplate>
         </Setter.Value>
       </Setter>
     </Style>
    

    您可以看到,通过重新模板化控件,您可以更改其可视化树。此模板中的可视化树只不过是一个包含ContentPresenterBorder(因此您可以看到按钮的内容)。我已经通过这种方式有效地从可视化树中删除了 ButtonChrome。

    【讨论】:

    【解决方案2】:

    查理的回答很好。我只是想补充对发生的事情的解释,而评论似乎并不合适。

    之所以一瞬间是绿色,然后是蓝色是因为默认主题的ButtonControlTemplate 已经有一个IsMouseOver Trigger 来改变背景。

    然后您在Style 中添加了另一个。这不会取代现有的,因为您可以在同一个属性和值上拥有多个 Triggers,它们具有非常不同的 Setters 并且做完全不同的事情。

    所以它试图同时做这两件事,并且首先做了绿色的。

    【讨论】:

    • 这就是我的想法。如果您不想要触发器,是否有任何方法可以简单地删除它,或者重新模板化控件是唯一的方法?
    • 据我所知,重新模板是唯一的方法。
    猜你喜欢
    • 2021-02-13
    • 2021-12-16
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    相关资源
    最近更新 更多