2

我设计了一个Button包含两个TextBlocks 的元素。一个带有实际文本,另一个带有图标(来自 Segoe UI Symbol)。

这是样式的代码:

<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;" />

我怎样才能做到这一点?-SetterContent已分配给 Text-TextBlock ...

谢谢你的帮助!

4

3 回答 3

2

编辑:我同意@meilke 的评论,但问题是你需要一个依赖属性来设置一个 TemplateBinding 所以请看下面的新类 ButtonWithIcon

您应该从 Button 继承并添加一个名为 IconContent 的 DependencyProperty :

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;" />
于 2013-09-27T12:41:06.813 回答
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的 for 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;" />
于 2013-09-27T12:38:39.573 回答
1

如果您不想子类化 Button 来添加您自己的属性,您可以使用Tag属性或附加属性

请注意,如果您使用附加属性,则需要绑定到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>
于 2013-09-27T13:04:25.757 回答