2013-11-04 58 views
1

我想为按钮创建一个模板,以防止控件在被禁用时灰色,它工作得很好,但由于某种原因,它不会改变背景一次我为它设置了一个颜色按钮属性。触发器不会改变背景

这里是我做的按钮:

<Style TargetType="Button" x:Key="TestButton"> 
     <Setter Property="SnapsToDevicePixels" Value="true" /> 
     <Setter Property="OverridesDefaultStyle" Value="true" /> 
     <Setter Property="MinHeight" Value="29px" /> 
     <Setter Property="MinWidth" Value="103px" /> 
     <Setter Property="Foreground" Value="Black" /> 
     <Setter Property="Background" Value="#EEEEEE"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Button"> 
        <Border TextBlock.Foreground="{TemplateBinding Foreground}" x:Name="Border"> 
         <Border.Background> 
          <SolidColorBrush Color="{TemplateBinding Background}" /> 
         </Border.Background> 
         <Border.BorderBrush> 
          <SolidColorBrush Color="Black" /> 
         </Border.BorderBrush> 
         <Border.BorderThickness> 
          <Thickness Top="0.75" Bottom="0.75" Right="0.75" Left="0.75"/> 
         </Border.BorderThickness> 
         <Border.CornerRadius> 
          <CornerRadius TopLeft="3" TopRight="3" BottomLeft="3" BottomRight="3"/> 
         </Border.CornerRadius> 
         <ContentPresenter Margin="2" 
         HorizontalAlignment="Center" 
         VerticalAlignment="Center" 
         RecognizesAccessKey="True" /> 
        </Border> 
        <!--Triggers--> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsMouseOver" Value="True"> 
          <Setter Property="Background" Value="#E1F3FD" /> 
         </Trigger> 
         <Trigger Property="IsPressed" Value="True"> 
          <Setter Property="Background" Value="#C4E9FF" /> 
          <Setter Property="Effect"> 
           <Setter.Value> 
            <DropShadowEffect Color="Black" Direction="500" ShadowDepth="1" BlurRadius="5" Opacity="0.5" /> 
           </Setter.Value> 
          </Setter> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Background}"/> 
          <Setter Property="Opacity" Value="0.5" /> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="True" > 
          <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Background}" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

当我把它给了我两个diferent结果,即工作的一个是:

<Button Style="{DynamicResource ResourceKey=TestButton}" Content="Button" Height="66" Name="button1" Width="149" Click="button1_Click" /> 

但是,当我添加一个背景,它停止改变背景由于某种原因:

<Button Style="{DynamicResource ResourceKey=TestButton}" Background="Orange" Content="Button" Height="66" Name="button1" Width="149" Click="button1_Click" /> 
+0

将Style =“Orange”添加到Style中,你应该很好。 –

+0

如何?如果我将它添加到按钮样式中,它不起作用,我不想将它添加到我的模板中,因为它应该与所有颜色兼容,因为用户将定义它。 我的意思是,如果用户在运行时改变颜色,整个模板仍然可以工作。 –

回答

2

它不会改变颜色,因为您使用您在MainWindow.xaml中定义的颜色“覆盖”颜色。

它称为依赖属性值优先。

要了解更多关于它来看看这个:

http://msdn.microsoft.com/en-us/library/ms743230.aspx

你的情况会发生什么事是你的风格和触发定义的背景,但然后设置在主窗口的值。 MainWindow中设置的值被认为是本地值,style中设置的值是“样式 - 值”。

如果你看看我给你的链接,你会发现本地值先于“样式 - 值”出现。

本地值非常强大。

这就是为什么即使在禁用状态下按钮仍然是橙色的原因。当触发器触发时,属性系统将尝试为背景查找值,并且它始终会找到本地值,因为这是最高优先值。

为了使其正常工作,在设置Button的背景值时,必须使用SetCurrentValue而不是SetValue。 (意味着你将不得不重写按钮的代码)

看看这个:

http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.setcurrentvalue.aspx

此方法用于通过编程设置自己的属性之一的值,而无需禁用的组件应用程序声明使用该属性。 SetCurrentValue方法更改属性的有效值,但现有的触发器,数据绑定和样式将继续工作。

编辑:

例子就明白了依赖项属性值优先级和命中测试。

<Window.Resources> 
    <Style TargetType="{x:Type Grid}"> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="True"> 
       <Setter Property="Background" Value="Yellow" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
    <Style TargetType="{x:Type TextBlock}"> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="True"> 
       <Setter Property="Background" Value="Red" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<Grid> 
    <TextBlock Height="20" Margin="40" Text="asdfasdfa" VerticalAlignment="Bottom"/> 
    <Rectangle Height="100" VerticalAlignment="Bottom" > 
     <Rectangle.Fill> 
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
       <GradientStop Offset="0"/> 
       <GradientStop Color="White" Offset="1"/> 
      </LinearGradientBrush> 
     </Rectangle.Fill> 
    </Rectangle> 
</Grid> 
+0

然后,没有办法真正改变只使用模板的背景?这是一个无赖,我讨厌它是如何通过禁用灰色,所以我想我自己的按钮将解决它... –

+0

嗨,你解决了你的问题?是的,有一种方法,但使用SetCurrentValue或通过欺骗一点点。 –

+0

你介意举个例子吗?我已阅读您迄今为止提供的内容,但未能使其工作。 –

2

只是注:Background属性是Brush类型的,所以你应该写

<Border Background="{TemplateBinding Background}" ...> 
    ... 
</Border> 

,而不是

<Border ...> 
    <Border.Background> 
     <SolidColorBrush Color="{TemplateBinding Background}" /> 
    </Border.Background> 
    ... 
</Border> 
+0

不知道为什么我这样做,改变了! –