我得到了以下设置:
<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>
然而,在启动我的应用程序时,我得到以下结果,这不是我想要的。当我手动设置我的按钮的Content
属性时,似乎忽略了所有字体属性。
实例:
我希望使用与右键相同的fontstyle和fontsize。我尝试使用StaticResource
和DynamicResource
手动指定样式,如下所示:
<Button Style="{StaticResource MetroButton}"....
但没有改变。
我想我需要实现一个覆盖现有格式的样式并将格式转移到TextBlock
元素,但我不知道如何做到这一点。
工作&#34;负载过滤器&#34;右边的按钮:
<Button x:Name="LoadFilter" Content="{Resx LoadFilters}" Margin="5" Grid.Column="2"/>
MahApps.Metro的标准按钮(MetroButton)包含在this文件中。
我应用于图标按钮的样式:
<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>
答案 0 :(得分:1)
在您的设置中,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>
然后我会在按钮上使用此样式
<Button Content="Delete" Style="{StaticResource MetroButton}" Tag="{StaticResource appbar_delete}"/>
<强>更新强> 利用ContentTemplate在使用现有模板的同时实现相同目标。
<Style x:Key="MetroIconButton" BasedOn="{StaticResource MetroButton}" TargetType="{x:Type Button}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate >
<StackPanel Orientation="Horizontal">
<Rectangle Height="9" Width="9" Margin="5 3" Stretch="Fill">
<Rectangle.Fill>
<VisualBrush Visual="{Binding Tag, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"/>
</Rectangle.Fill>
</Rectangle>
<ContentControl Content="{Binding}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
除了样式MetroIconButton
之外,用法保持不变
<Button Content="Delete" Style="{StaticResource MetroIconButton}" Tag="{StaticResource appbar_delete}"/>
我使用Tag
属性来保存图标,以便它可以即插即用,但更好的方法是使用附加属性。 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方法,而不是黑客攻击其他可能无法保证按预期运行的属性。