2013-09-27 13 views
2

我已經設計了一個Button元素,其中包含兩個TextBlock s。一個帶有實際文字,另一個帶有一個圖標(來自Segoe UI Symbol)。帶有多個TextBlocks的XAML樣式按鈕

這是風格的代碼:

<Style x:Key="ButtonSettingsStyle" TargetType="Button"> 
    <Setter Property="Content" Value=""/> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="Foreground" Value="White"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
     <ControlTemplate TargetType="Button"> 
      <StackPanel Background="Transparent" Orientation="Horizontal" Height="60"> 
      <VisualStateManager.VisualStateGroups> 
       ... 
      </VisualStateManager.VisualStateGroups> 
      <TextBlock 
       x:Name="Icon" 
       Text="&#xE115;" 
       Margin="10,0,5,0" 
       Width="40" 
       Foreground="{TemplateBinding Foreground}" 
       FontSize="32" 
       VerticalAlignment="Center" 
       RenderTransformOrigin="0.5,0.5" 
       FontFamily="Segoe UI Symbol"></TextBlock> 
      <TextBlock 
       x:Name="Text" 
       Text="{TemplateBinding Content}" 
       VerticalAlignment="Center" 
       Style="{StaticResource TextBlockListBoldItem}" 
       Foreground="{TemplateBinding Foreground}" /> 
      </StackPanel> 
     </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    </Style> 

問題:

我也希望圖標的TextBlock有一個自定義圖標,因此定製Text - 特性和使用也許這樣(我真的不知道這應該如何工作):

<Button Style="{StaticResource ButtonSettingsStyle}" Content="Settings" IconContent="&#xE115;" /> 

我該如何做到這一點? Content -Setter已經分配給Text-TextBlock ...

感謝您的幫助!

回答

2

編輯:我同意@meilke評論,但問題是你需要一個依賴屬性t o設置爲一個TemplateBinding所以見下文

新類ButtonWithIcon你應該從按鈕繼承並添加一個DependencyProperty名爲IconContent:

public class ButtonWithIcon : Button 
{ 
    public static readonly DependencyProperty IconContentProperty = 
     DependencyProperty.Register("IconContent", typeof (string), typeof (ButtonWithIcon), new PropertyMetadata(default(Icon))); 

    public string IconContent 
    { 
     get { return (string) GetValue(IconContentProperty); } 
     set { SetValue(IconContentProperty, value); } 
    } 
} 

而且使用這樣的:

<Style x:Key="ButtonSettingsStyle" TargetType="local:ButtonWithIcon"> 
    <Setter Property="Content" Value=""/> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="Foreground" Value="White"/> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="local:ButtonWithIcon"> 
     <StackPanel Background="Transparent" Orientation="Horizontal" Height="60"> 
      <VisualStateManager.VisualStateGroups> 
      ... 
      </VisualStateManager.VisualStateGroups> 
      <TextBlock 
      x:Name="Icon" 
      Text="{Binding IconContent, RelativeSource={RelativeSource TemplatedParent}}" 
      Margin="10,0,5,0" 
      Width="40" 
      Foreground="{TemplateBinding Foreground}" 
      FontSize="32" 
      VerticalAlignment="Center" 
      RenderTransformOrigin="0.5,0.5" 
      FontFamily="Segoe UI Symbol"></TextBlock> 
      <TextBlock 
      x:Name="Text" 
      Text="{TemplateBinding Content}" 
      VerticalAlignment="Center" 
      Style="{StaticResource TextBlockListBoldItem}" 
      Foreground="{TemplateBinding Foreground}" /> 
     </StackPanel> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

<local:ButtonWithIcon Style="{StaticResource ButtonSettingsStyle}" Content="Settings" IconContent="&#xE115;" /> 
+0

不要忘記調整好的模板... – meilke

+1

另外,你不需要構造函數。在這種簡單的情況下,'Button'將完成所需的一切。 – meilke

+0

感謝您對我的回答建議的編輯:但您可以使用'{TemplateBinding bla}'和'{Binding bla,RelativeSource = {RelativeSource TemplatedParent}}' – meilke

1

子類Button用自定義屬性IconContent來實現。

這是新類:

public class MyButton : Button 
{ 
    public static readonly DependencyProperty IconContentProperty = 
    DependencyProperty.Register("IconContent", typeof (string), typeof (ButtonWithIcon), new PropertyMetadata(default(Icon))); 

    public string IconContent 
    { 
    get { return (string) GetValue(IconContentProperty); } 
    set { SetValue(IconContentProperty, value); } 
    } 
} 

這裏是調整後的風格(注意,IconContentTemplateBinding):

<Style x:Key="ButtonSettingsStyle" TargetType="local:MyButton"> 
    <Setter Property="Content" Value=""/> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="Foreground" Value="White"/> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="local:MyButton"> 
     <StackPanel Background="Transparent" Orientation="Horizontal" Height="60"> 
      <VisualStateManager.VisualStateGroups> 
      ... 
      </VisualStateManager.VisualStateGroups> 
      <TextBlock 
      x:Name="Icon" 
      Text="{TemplateBinding IconContent}" 
      Margin="10,0,5,0" 
      Width="40" 
      Foreground="{TemplateBinding Foreground}" 
      FontSize="32" 
      VerticalAlignment="Center" 
      RenderTransformOrigin="0.5,0.5" 
      FontFamily="Segoe UI Symbol"></TextBlock> 
      <TextBlock 
      x:Name="Text" 
      Text="{TemplateBinding Content}" 
      VerticalAlignment="Center" 
      Style="{StaticResource TextBlockListBoldItem}" 
      Foreground="{TemplateBinding Foreground}" /> 
     </StackPanel> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

這裏是用法:

<local:MyButton Style="{StaticResource ButtonSettingsStyle}" Content="Settings" IconContent="&#xE115;" /> 
+0

非常感謝你的努力。看看我在Florent的帖子中的評論,看看我爲什麼接受它作爲答案。 –

1

如果你不」想要子類按鈕來添加自己的屬性,可以使用Tag屬性或an attached property

請注意,如果您使用的附加屬性,則需要結合TemplatedParent而不是使用TemplateBinding

{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, 
     Path=local:AttachedProperties.IconContent} 

我不知道你爲什麼會想限制你的按鈕,只接受文字。通常按鈕接受任何內容並使用ContentPresenter。就個人而言,我會鍵入IconContent財產object和這樣定義的模板:

<ContentPresenter x:Name="Icon" Content="{TemplateBinding IconContent}" /> 
<ContentPresenter x:Name="Text" /> 

然後將其設置是這樣的:

<Button> 
    <Button.IconContent> 
     <TextBlock Style="{StaticResource IconTextBlockStyle}" Text="&#xE115;" /> 
    </Button.IconContent> 
</Button> 
+0

感謝您的回答。這似乎也是解決我的問題的好方法。其他解決方案對我來說效果更好,因爲這是真正只需要文本的特定按鈕(不是我應用中的所有按鈕),而且我需要爲它們編寫更少的XAML。但現在我知道如何做更復雜的風格的按鈕。謝謝你! –