2013-09-27 4 views
2

Я нарисовал элемент Button, который содержит два TextBlock s. Один с фактическим текстом, а другой с иконкой (из Symgo UI Symbol).Кнопка стиля 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> 

Проблема:

Я также хочу Icon-TextBlock иметь собственный значок, поэтому обычай Text -property и использовать возможно, так (я действительно не знаю, как это должно работать):

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

Как я могу это достичь? Content -Сеть уже назначена на Text-TextBlock ...

Благодарим за помощь!

ответ

2

Изменить: я согласен с комментарием @meilke, но проблема в том, что вам нужна зависимость зависимости t о установить TemplateBinding так увидеть новый класс ButtonWithIcon ниже

Вы должны наследоваться от Button и добавить 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); } 
    } 
} 

Вот скорректированный стиль (обратите внимание на новый TemplateBinding для IconContent):

<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

Спасибо большое за ваши усилия. Смотрите мой комментарий в постере Флорана, чтобы понять, почему я принял его в качестве ответа. –

1

Если вы не» t хотите подклассу Button, чтобы добавить ваше собственное имущество, вы можете использовать свойство Tag или an attached property.

Обратите внимание, что если вы используете вложенное свойство, вам нужно будет связываться с TemplatedParent вместо использования TemplateBinding:

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

Я не знаю, почему вы хотите, чтобы ограничить кнопки принимать только текст. Обычно кнопки принимают любой контент и используют ContentPresenter s. Лично я хотел бы ввести свойство 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 для них. Но теперь я знаю, как делать более сложные стилизованные кнопки. Благодаря вам! –

Смежные вопросы