2014-10-10 22 views
4

當涉及到綁定到ControlTemplate中的效果的顏色屬性時,我看到一些奇怪的行爲。當直接設置值時,我可以將顏色定義爲字符串(例如「紅色」)或者將其定義爲十六進制值(例如#FFFF0000)。如何將WPF效果顏色綁定到控制模板的前景或背景

但是,當使用綁定時,它只在顏色被定義爲字符串時才起作用,這是ControlTemplate樣式中的問題,因爲我想使用TemplateParent屬性的顏色,它們以Hex值。

例如。看看下面的XAML(抱歉,我知道這是很長,但我想顯示所有的情況下):

<Window x:Class="EffectTest.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"> 

    <Window.Resources> 

     <!-- 
     STYLE 1 
     This works, as the Color is hard coded, but note that the hard 
     coded value is identicle to the value in Style 2 (which doesn't work). 
     --> 
     <Style x:Key="Style1" TargetType="{x:Type Button}"> 
      <Style.Setters> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type Button}"> 
          <Border Width="{TemplateBinding Width}" 
            Height="{TemplateBinding Height}" 
            Background="{TemplateBinding Foreground}"> 
           <Border.Effect> 
            <DropShadowEffect Color="#FFFF0000"/> 
           </Border.Effect> 
           <TextBlock Foreground="White" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}"/> 
          </Border> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style.Setters> 
     </Style> 

     <!-- 
     STYLE 2 
     This fails (the dropshadow appears black) even through the value being bound to is the same as Style 1. 
     --> 
     <Style x:Key="Style2" TargetType="{x:Type Button}"> 
      <Style.Setters> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type Button}"> 
          <Border Width="{TemplateBinding Width}" 
            Height="{TemplateBinding Height}" 
            Background="{TemplateBinding Foreground}"> 
           <Border.Effect> 
            <!--NOTE: TemplateBinding does not work at all... <DropShadowEffect Color="{TemplateBinding Background}"/>--> 
            <DropShadowEffect Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}"/> 
           </Border.Effect> 
           <TextBlock Foreground="White" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}"/> 
          </Border> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style.Setters> 
     </Style> 

     <!-- 
     STYLE 3 
     This works, but note that I am binding to "Name" for the Color, which just happens to be a valid color "Red". 
     --> 
     <Style x:Key="Style3" TargetType="{x:Type Button}"> 
      <Style.Setters> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type Button}"> 
          <Border Width="{TemplateBinding Width}" 
            Height="{TemplateBinding Height}" 
            Background="{TemplateBinding Foreground}"> 
           <Border.Effect> 
            <DropShadowEffect Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Name}"/> 
           </Border.Effect> 
           <TextBlock Foreground="White" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Name}"/> 
          </Border> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style.Setters> 
     </Style> 
    </Window.Resources> 

    <StackPanel Width="150"> 
     <Button Style="{StaticResource Style1}" Foreground="LightBlue" Background="Red"></Button> 
     <Separator Visibility="Hidden" Height="5"/> 
     <Button Style="{StaticResource Style2}" Foreground="LightBlue" Background="Red"></Button> 
     <Separator Visibility="Hidden" Height="5"/> 
     <Button Style="{StaticResource Style3}" Foreground="LightBlue" Name="Red"></Button> 
    </StackPanel> 
</Window> 

結果:

Results

這是爲什麼?有沒有辦法解決它?我希望能夠在控件模板的效果中使用Button的Background和Foreground屬性。

+0

案例2:你有約束力的錯誤,因爲TemplatedParent的'Background'的類型不是'Color',它是'System.Windows.Media.Brush'。 – kennyzx 2014-10-10 02:09:54

+1

解決方法是定義一個轉換器將Brush(本例中爲SolidColorBrush)轉換爲Color。 – kennyzx 2014-10-10 02:25:25

+0

感謝您的替代解決方案@kennyzx! – Goose 2014-10-10 15:54:14

回答

5

是的,背景是一個畫筆對象,如果您的模板背景屬性是純色,那麼您可以將顏色屬性綁定到背景的顏色屬性,如 {Binding RelativeSource = {RelativeSource TemplatedParent},Path = Background。顏色} 或者您可以使用轉換器。

更新代碼示例:

<Style x:Key="Style2" TargetType="{x:Type Button}"> 
    <Style.Setters> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        <Border Width="{TemplateBinding Width}" 
          Height="{TemplateBinding Height}" 
          Background="{TemplateBinding Foreground}"> 
         <Border.Effect> 
          <!-- Now uses Background.Color --> 
          <DropShadowEffect Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}"/> 
         </Border.Effect> 
         <TextBlock Foreground="White" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}"/> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style.Setters> 
</Style>