如何为WPF应用程序设置默认字体?

89

我希望能够为我的WPF应用程序定义字体系列,最好是使用从App.xaml引用的资源字典作为主题。我已经尝试创建了一个如下所示的Style

<Style TargetType="{x:Type Control}">
    <Setter Property="FontFamily" Value="Segoe UI" />            
</Style>

但这并不起作用。将类型设置为TextBlock对大多数控件有效,但是有些控件不适用。

我知道可以在窗口上设置字体,并使该窗口的所有子控件继承该字体。 但我认为任何对话框窗口都会恢复默认字体,这不完全是我想要的。

有什么建议吗?

6个回答

68

假设您的 Window 子类没有覆盖 DefaultStyleKey,那么您可以将它简单地添加到您的 Window 样式中,因为 TextElement.FontFamilyProperty 是一个继承属性:

<Style TargetType="{x:Type Window}"> 
    <Setter Property="FontFamily" Value="Segoe UI" />             
</Style> 

InitializeComponent调用之后,您还需要将以下内容添加到您的应用构造函数中:

FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
{
    DefaultValue = FindResource(typeof(Window))
});

工作原理:在App对象完成初始化后,其中指定的窗口样式将成为所有窗口的默认样式。


1
@Ray:你的代码片段肯定是不起作用的。因为你必须使用从Window派生的类,还需要一些额外的代码和/或XAL参与。 - Matze
1
@Matze:这让我感到非常困惑,因为我在我的生产应用程序中使用的代码恰好就是我在答案中写的。最终我弄清楚了为什么它对我有效但对你无效,并更新了我的答案以纠正问题。非常感谢你提醒我注意这个问题。 - Ray Burns
2
在你的Application类的protected override void OnStartup(StartupEventArgs e)方法中,或者你需要创建自己的Main方法来直接调用App的InitializeComponent。感谢您的努力帮助! - Matze
3
这对我没用。我在InitializeComponent()调用之后直接放置了Style = (Style)FindResource(typeof(Window));,这对我有效。感谢http://avolk.parivedasolutions.com/2011/03/default-wpf-application-font.html。 - user1151923
但它不影响文本框,那么该怎么办呢? - henon
显示剩余8条评论

30

大多数提出的解决方案对我都没有用。我的简单解决方案是:

将以下内容添加到 App.xaml 中:

<Style TargetType="{x:Type Window}">
    <Setter Property="FontSize"
            Value="14" />
</Style>

在您的 MainWindow 构造函数中添加以下内容(在 InitializeComponent 后):

Style = (Style)FindResource(typeof(Window));

22

实际上,您可以获取一个完整的XAML解决方案,将此处其他答案的某些部分结合起来。

如果您的主窗口名为WinMain(在加载所有其他窗口之前加载的那个),只需添加对名为WinAll的样式的引用即可。

<Window x:Class="MyNamespace.WinMain"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="WinMain" Height="450" Width="800"
    Style="{StaticResource WinAll}">

然后以这种方式定义您的样式

<Style x:Key="WinAll" TargetType="{x:Type Window}">
    <Setter Property="FontFamily"
        Value="Comic Sans MS" />
    <Setter Property="FontSize"
        Value="14" />
</Style>

3
乍一看可能不太优美,但对于VS2015+和.NET Framework 4.5.2来说,这是我找到的所有答案中最好的方式。 - Val
1
我认为这是最优雅的版本。当使用热重载功能时,如果使用Jowen的答案,则无法进行热重载。但是,使用此答案很容易进行热重载,因为它只被视为普通样式。 - darophi
1
这正是我正在寻找的。谢谢! - Louis van Tonder
3
很好,样式只需要放在App.xaml中。 - Martin Braun

17

一个简单的编程方法是:

public MainWindow()
{
    this.FontFamily = new FontFamily("Segoe UI");
}

这个对我有用,使用来自Rays答案的XAML(以获取编辑器视图和运行时字体正确)。 - mgear

10
我找到了这个:

我发现了这个:

TextElement.FontFamilyProperty.OverrideMetadata(
typeof(TextElement),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));

TextBlock.FontFamilyProperty.OverrideMetadata(
typeof(TextBlock),
new FrameworkPropertyMetadata(
    new FontFamily("Comic Sans MS")));

0
尝试在 App.xaml 中使用这个简单的解决方法(无需代码后台):
<SolidColorBrush x:Key="ForeBrush" Color="Blue" />

<Style x:Key="GenericTextStyle">
    <!-- Generic control forecolor definition -->
    <Setter Property="Control.Foreground" Value="{StaticResource ForeBrush}" />

    <!-- Add a definition for each unworking nested control -->
    <Style.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="{StaticResource ForeBrush}" />
        </Style>
    </Style.Resources>
</Style>

只需将您的Windows样式绑定到此处即可。对我来说完美地运作。只有一些属性需要在嵌套树中定义。例如,属性FontSize只能在通用部分中指定。

我不知道为什么需要这样做。这很奇怪,因为标签应该是从控件派生而来的。有人对此有任何想法吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接