C# 自定义按钮内容时忽略按钮字体属性

C# 自定义按钮内容时忽略按钮字体属性,c#,wpf,mahapps.metro,C#,Wpf,Mahapps.metro,我得到了以下设置: <Button x:Name="DeleteFilter" Margin="5" Grid.Column="1" Padding="2"> <StackPanel Orientation="Horizontal"> <Rectangle Height="9" Width="9" Stretch="Fill" Margin="5 3"> <Rectangle.Fill>

我得到了以下设置:

<Button x:Name="DeleteFilter" Margin="5" Grid.Column="1" Padding="2">
    <StackPanel Orientation="Horizontal">
        <Rectangle Height="9" Width="9" Stretch="Fill" Margin="5 3">
            <Rectangle.Fill>
                <VisualBrush Visual="{StaticResource appbar_delete}"/>
            </Rectangle.Fill>
        </Rectangle>
        <TextBlock Text="{Resx DeleteFilter}"/>
    </StackPanel>
</Button>
但一切都没有改变

我想我需要实现一种样式来覆盖现有的样式,并将格式传输到
TextBlock
元素,但我不知道如何做到这一点


右侧的工作“加载过滤器”按钮:

<Button x:Name="LoadFilter" Content="{Resx LoadFilters}" Margin="5" Grid.Column="2"/>

Metro的标准按钮(MetroButton)包含在该文件中

我应用于图标按钮的样式:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="MetroIconButton" BasedOn="{StaticResource MetroButton}" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Height="9" Width="9" Margin="5 3" Stretch="Fill">
                            <Rectangle.Fill>
                                <VisualBrush Visual="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"/>
                            </Rectangle.Fill>
                        </Rectangle>
                        <ContentPresenter/>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

在您的设置中,StackPanel用作不太理想的内容,您可以创建包含模板和字体所需属性设置器的样式,以便在整个应用程序中保持所需按钮的一致性

所以如果我尝试为你创建一个按钮样式

<Style x:Key="MetroButton" TargetType="{x:Type Button}">
  <Setter Property="FontSize" Value="13"/>
  <Setter Property="Template">
      <Setter.Value>
          <ControlTemplate TargetType="Button">
              <StackPanel Orientation="Horizontal">
                  <Rectangle Height="9" Width="9" Margin="5 3" Stretch="Fill">
                      <Rectangle.Fill>
                          <VisualBrush Visual="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"/>
                      </Rectangle.Fill>
                  </Rectangle>
                  <ContentPresenter/>
              </StackPanel>
          </ControlTemplate>
      </Setter.Value>
  </Setter>
</Style>
我正在使用
标记
属性来保存图标,因此它对您来说是即插即用的,但更好的方法是使用附加属性
l:ExtraProperties.Icon={StaticResource appbar_delete}“
,如果您也需要,我可以提供一个示例

实际上,在以前的样式中,我们覆盖了MetroButton样式中定义的模板,因此失败了。在查看MetroButton样式的原始实现后,我提出了激活相同样式的ContentTemplate方法。因此,我们将不设置模板,而是设置MetroButton样式将拾取并应用的内容模板与内容一致

使用附加属性

声明继承DependencyObject或其任何派生类以及所需属性的类,如下所述

class ExtraProperties: DependencyObject
{
    public static Visual GetIcon(DependencyObject obj)
    {
        return (Visual)obj.GetValue(IconProperty);
    }

    public static void SetIcon(DependencyObject obj, Visual value)
    {
        obj.SetValue(IconProperty, value);
    }

    // Using a DependencyProperty as the backing store for Icon.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IconProperty = DependencyProperty.RegisterAttached("Icon", typeof(Visual), typeof(ExtraProperties), new PropertyMetadata(null));
}
将名称空间添加到xaml

<Window x:Class="Example.MainWindow"
    ...
    xmlns:l="clr-namespace:Example">

然后将样式更改为

<VisualBrush Visual="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=(l:ExtraProperties.Icon)}"/>

以及用作

<Button Content="Delete" Style="{StaticResource MetroIconButton}" l:ExtraProperties.Icon="{StaticResource appbar_delete}"/>


使用附加属性更像是WPF方法,而不是黑客攻击可能无法保证按预期运行的其他属性。

您一定是弄错了,或者没有充分描述您的问题。如果您在
按钮上设置
FontFamily
属性,无论是内联的还是应用的
样式的
,都将是错误的影响
内容中的
文本块
。如果您的代码块不起作用,请编辑您的代码示例,以实际显示问题的工作示例。@Sheridan我是这么想的,但不知怎的,它不起作用。有关详细信息,请参阅我的更新。问题是
MetroButton
是样式基础(正如你可能在我的问题图片中看到的,右边的按钮)我希望我的按钮继承样式,使其看起来与右边的一模一样…只是有一个小图标。我应用了你的样式(谢谢)到我的按钮并添加了一个
BasedOn
属性,但继承以某种方式失败。是否可以查看原始MetroButton样式?指定BasedOn时是否有任何特定错误?这些将帮助我们通过添加图标实现适当的样式。是的,请参阅问题中的“我的更新”。有一个指向fi的链接le原MetroButton的实现位置。不,我没有错误。感谢您的努力。我找到了您所说的失败风格的真正含义,请参阅更新的答案。这很好。路径是可选的,但有时出于各种原因被认为是必要的。从现在开始,我还会将其包括在我的示例中,以减少出现错误的机会。A我很高兴这个解决方案对你有效。
class ExtraProperties: DependencyObject
{
    public static Visual GetIcon(DependencyObject obj)
    {
        return (Visual)obj.GetValue(IconProperty);
    }

    public static void SetIcon(DependencyObject obj, Visual value)
    {
        obj.SetValue(IconProperty, value);
    }

    // Using a DependencyProperty as the backing store for Icon.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IconProperty = DependencyProperty.RegisterAttached("Icon", typeof(Visual), typeof(ExtraProperties), new PropertyMetadata(null));
}
<Window x:Class="Example.MainWindow"
    ...
    xmlns:l="clr-namespace:Example">
<VisualBrush Visual="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=(l:ExtraProperties.Icon)}"/>
<Button Content="Delete" Style="{StaticResource MetroIconButton}" l:ExtraProperties.Icon="{StaticResource appbar_delete}"/>