2016-10-10 109 views
0

我想爲「顏色色板」按鈕定義WPF ControlTemplate。從本質上講,我希望能夠使用該模板是這樣的:在ControlTemplate DataTrigger中更改按鈕背景

<Button Template="{StaticResource SwatchButtonTemplate}" Background="{Binding ActiveColor}">

ActiveColor是數據上下文Color屬性。我已經能夠實現,與此模板:

<ControlTemplate x:Key="SwatchButtonTemplate" TargetType="{x:Type Button}"> 
    <Border Name="OuterBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{StaticResource BorderBrush}" Background="{TemplateBinding Background}"> 
     <Border Name="InnerBorder" BorderThickness="0" BorderBrush="White" Background="{TemplateBinding Background}"> 
      <ContentPresenter/> 
     </Border> 
    </Border> 
    <ControlTemplate.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter TargetName="OuterBorder" Property="BorderThickness" Value="1"/> 
      <Setter TargetName="InnerBorder" Property="BorderThickness" Value="1"/> 
      <Setter TargetName="OuterBorder" Property="BorderBrush" Value="{StaticResource MouseOverAccentBrush}"/> 
     </Trigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

但現在想要做的是使用一個特殊的刷按鈕背景是什麼我如果顏色是透明的(例如,顯示一個紅色的「X」在背景中如果顏色是透明的)。

我似乎無法弄清楚如何在檢查背景顏色的模板中設置觸發器,如果​​它是透明的,則使用不同的Brush作爲Background屬性。我已經嘗試在模板中添加一個DataTrigger:

<ControlTemplate.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      ... 
     </Trigger> 
     <DataTrigger Binding="{TemplateBinding Background}" Value="#00000000"> 
      <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}"/> 
     </DataTrigger> 
    </ControlTemplate.Triggers> 

但是我在使用這個時遇到XamlParseException。

編輯:此模板的全用法是在樣本按鈕的列表,並且該列表的源極結合到稱爲ObservableCollection<Brush>ColorList填充SolidColorBrushes(其中一個是透明的)

<ItemsControl ItemsSource="{Binding ColorList}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Button x:Name="button" Background="{Binding}" 
        Template="{StaticResource SwatchButtonTemplate}"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <UniformGrid Height="20" Rows="1" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

並全面模板定義:

<ControlTemplate x:Key="SwatchButtonTemplate" TargetType="{x:Type Button}"> 
    <Border Name="OuterBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{StaticResource BorderBrush}" Background="{TemplateBinding Background}"> 
     <Border Name="InnerBorder" BorderThickness="0" BorderBrush="White" Background="{TemplateBinding Background}"> 
      <ContentPresenter/> 
     </Border> 
    </Border> 
    <ControlTemplate.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter TargetName="OuterBorder" Property="BorderThickness" Value="1"/> 
      <Setter TargetName="InnerBorder" Property="BorderThickness" Value="1"/> 
      <Setter TargetName="OuterBorder" Property="BorderBrush" Value="{StaticResource MouseOverAccentBrush}"/> 
     </Trigger> 
     <DataTrigger Binding="{Binding Background, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="#00ffffff"> 
      <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}"/> 
     </DataTrigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 
+0

'TemplateBinding'相當有限。當它給你一個SadTromboneException,就像它經常這樣做,總是嘗試'Binding =「{Binding Background,RelativeSource = {RelativeSource TemplatedParent}}」' –

+0

@EdPlunkett我剛剛嘗試過,但後來我得到這個錯誤:'BindingExpression path錯誤:未在'object''ContentPresenter'(Name ='')'上找到'Background'屬性。 ......這是由於我的模板是如何構建的嗎? –

+0

這是由於ContentPresenter沒有名爲Background的屬性,但是某處嘗試設置該屬性無論如何。我不得不在當前狀態下看到完整模板,以瞭解它如何設置ContentPresenter上的背景。如果TargetName仍然是InnerBorder,並且InnerBorder仍然是邊界的名稱,那麼也許你在其他地方做這個。 –

回答

0

感謝@EdPlunkett您的建議,以避免「{TemplateBinding ...}」中的數據觸發。 (只XAML)的解決方案是使用一種 「自我」 相對來源:

<ControlTemplate x:Key="SwatchButtonTemplate" TargetType="{x:Type Button}"> 
    <Border Name="OuterBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{StaticResource BorderBrush}" Background="{TemplateBinding Background}"> 
     <Border Name="InnerBorder" BorderThickness="0" BorderBrush="White" Background="{TemplateBinding Background}"> 
      <ContentPresenter/> 
     </Border> 
    </Border> 
    <ControlTemplate.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter TargetName="InnerBorder" Property="BorderThickness" Value="1" /> 
     </Trigger> 
     <DataTrigger Binding="{Binding Path=Background.Color, RelativeSource={RelativeSource Self}}" Value="#00ffffff"> 
      <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}" /> 
     </DataTrigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

(也注意到,Colors.Transparent是#00FFFFFF,不#00000000,因爲我以爲)。

0

你可以用這樣的結合Button類型的anchestor修復:

<ControlTemplate.Triggers> 
    <Trigger Property="IsMouseOver" Value="True"> 
     ... 
    </Trigger> 
    <DataTrigger Binding="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}" Value="#00000000"> 
     <Setter TargetName="InnerBorder" Property="Background" Value="{StaticResource transparent_swatch_brush}"/> 
    </DataTrigger> 

這將使用Background屬性從Button