WPF全局字体大小


73

我正在创建WPF应用,我想知道能够更改ui中每个元素的字体大小的最佳方法。我是否创建资源字典并设置样式以设置我使用的所有控件的字体大小?

最佳做法是什么?

Answers:


100

我会这样:

<Window.Resources>
        <Style TargetType="{x:Type Control}" x:Key="baseStyle">
            <Setter Property="FontSize" Value="100" />
        </Style>
        <Style TargetType="{x:Type Button}" BasedOn="{StaticResource baseStyle}"></Style>
        <Style TargetType="{x:Type Label}" BasedOn="{StaticResource baseStyle}"></Style>
        <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource baseStyle}"></Style>
        <Style TargetType="{x:Type ListView}" BasedOn="{StaticResource baseStyle}"></Style>
        <!-- ComboBox, RadioButton, CheckBox, etc... -->
    </Window.Resources>

这样,如果我想更改所有控件,则只需要更改“ baseStyle”样式,其余样式就可以继承。(这就是基于属性的属性,如果您在继承的样式内创建其他设置器,则也可以扩展基本样式)


3
并且,如果您需要即时更改字体大小,请确保在“样式”和“ baseStyle”的样式引用中都将它们全部声明为DynamicResource。
杰夫·韦恩

认真吗?我尝试这样做,但出现此错误:属性'BaseOn'不支持'DynamicResourceExtension'类型的值。我只是将代码从StaticResource更改为DynamicResource。您认为缺少什么?
卡洛(Carlo)

1
忘了那个小问题。我们将所有声明设置为按控件声明的Setter,以便我们没有庞大的层次结构。这篇文章解释得很好。stackoverflow.com/questions/585429/…–
杰夫·韦恩

我对此问题有点好奇,因此我继续进行一些测试,但是似乎一旦设置并使用了StaticResource,就无法对其进行修改。如果您想在应用程序中的某个时间更改大小,可能需要其他解决方案。
卡洛(Carlo)

2
@Ian Boyd:但是那家伙只想更改他所有控件中的字体大小,而不是控件的大小。您所说的是一个完全不同的问题。
卡罗

43

FontSizeProperty从父控件继承。因此,您只需要更改主窗口的FontSize。

如果您不需要动态行为,则应该可以:

为您的ResourceDictionary添加Window样式

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

将样式应用于您的主窗体(不会被隐式应用,因为它是派生类型)

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

这听起来比标记为解决方案的答案更好。我将继续使用它,无论如何它的代码要少得多。
Koert van Kleef

2
编辑:不起作用(在任何情况下都使用Framework 4.5)。
Koert van Kleef 2013年

@KoertvanKleef-它在.NET 4.5上对我有效,您看到什么问题?
joshcomley

2
为什么要为单个元素创建样式?为什么不<Window FontSize="15">直接在元素上?
分钟

这比公认的解决方案更干净,更简单。
杰里米·莫伦

32

<Window> 具有属性FontSize。

因此,如果要更改该窗口中所有元素的字体大小,可以在element中设置所需的字体大小。

<Window FontSize="12">

</Window>

通过设置器将其应用到Window无效(虽然看起来像在设计器视图中一样),但是这种方法确实有效,并且是解决该问题的荒谬简单方法。
乔纳斯(Jonas)

这很棒!它可以在大约95%的应用程序中运行。(功能区按钮和某些其他控件除外)
Yonatan Tuchinsky,

@YonatanTuchinsky:当它不起作用时,可能是因为具有较高优先级的提供程序确定了依赖项属性值(例如,操作系统主题的提供程序,此优先级列表中的#9,而继承仅是#10)。
分钟

30

另一个选择是将FontFamily和FontSize定义为资源。

<FontFamily x:Key="BaseFontFamily">Calibri</FontFamily>
<sys:Double x:Key="BaseFontSize">12</sys:Double>

这样,您就可以在设置器中使用它们。


这最适合我,因为它允许您使用{DynamicResource}并在运行时更改字体大小。
彼得

6
不得不导入xmlns:sys =“ clr-namespace:System; assembly = mscorlib”,并且此方法运行完美。
dynamiclynk 2014年

10
Application.Current.MainWindow.FontSize = _appBodyFontSize;

这样,您还可以在运行时更改字体大小。


6

TextElement.FontSize 是一个继承属性,这意味着您只需在根元素处设置字体大小,所有子元素都将使用该大小(只要您不手动更改它们)


重要提示:“只要您不手动更改它们”。我花了一些时间弄清楚字体继承确实起作用了,因为我手动将其设置为父级。
彼得·胡伯

这应该是选定的答案。@PeterHuber:依赖关系属性依赖于具有某些预定优先级的多个值提供程序。设置局部值具有最高优先级(动画和强制除外,优先级规则除外)。
分钟

4

对于WPF中的任何样式,您应该有一个单独的资源字典,其中包含应用程序的样式。

如果您希望单个字体大小在整个应用程序中重复使用,则只需为该字体大小创建样式。您可以为它指定一个唯一的名称/键来显式使用,也可以设置将在整个应用程序中超越的targetType。

显式密钥:

<Style
    x:Key="MyFontSize"
    TargetType="TextBlock">
    <Setter
        Property="FontSize"
        Value="10" />
</Style>

<Control
    Style="{StaticResource MyFontSize}" />

*请注意,此样式可以与具有contentPresenters的控件一起使用

对于应用程序中的所有文本块:

<Style
    TargetType="TextBlock">
    <Setter
        Property="FontSize"
        Value="10" />
</Style>

<TextBlock
        Text="This text will be size 10" />

1
如果要在整个应用程序中重复使用单个字体大小,则只需创建一种样式”:这与dependency属性的目的矛盾FontSizeProperty依赖关系属性原则上可以在逻辑树中继承,因此,除非有特殊需要(例如,仅在中间节点上具有不同的字体大小),否则在根元素上设置字体大小就足够了。更新值将触发所有子项的更新。
分钟

2

如果需要以编程方式更改全局FontSize而不是静态(XAML),以对所有窗口都应用一次,则可以执行以下操作:

TextElement.FontSizeProperty.OverrideMetadata(
            typeof(TextElement),
            new FrameworkPropertyMetadata(16.0));

        TextBlock.FontSizeProperty.OverrideMetadata(
            typeof(TextBlock),
            new FrameworkPropertyMetadata(16.0));

此值可应用于任何TextBlock,Labels以及任何窗口中的几乎所有文本,而尚未定义显式的FontSize。但这对TextBox并没有影响,您必须为其编写类似的代码或任何其他特殊控件。


这比元素<Style>上的a更好TextBlock,因为否则您将不得不BasedOn在覆盖它的任何地方使用它!
bytecode77

1

要使用ctrl-mousewheel动态地全局更改字体大小,请执行以下操作:

XAML:

<Window Name="MainWindow" ... PreviewMouseWheel="MainWindow_PreviewMouseWheel">

后面的代码:

private void MainWindow_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    if ((Keyboard.Modifiers & ModifierKeys.Control) != 0)
    {
        if (e.Delta > 0)
            ++mainCtrl.FontSize;
        if (e.Delta < 0 && mainCtrl.FontSize > 1)
             --mainCtrl.FontSize;
    }
}

0

在XAML中使用资源是必经之路。尽管对于这个问题有很多很好的答案,但是我想在资源范围内加上两美分。

为了在项目的所有Windows和用户控件中具有全局可访问性,您可以将资源放在App.xaml文件中

<Application.Resources>
    <Style TargetType="{x:Type Control}" x:Key="GlobalFontSize">
        <Setter Property="FontSize" Value="28"/>
    </Style>
</Application.Resources>

为了获得Window级别的可访问性,您可以将资源放在Window的xaml文件中

<Window.Resources>
    <Style TargetType="{x:Type Control}" x:Key="GlobalFontSize">
        <Setter Property="FontSize" Value="28"/>
    </Style>
</Window.Resources>

例如,您甚至可以在控制级别使用它

<DockPanel.Resources>
    <Style TargetType="{x:Type Control}" x:Key="GlobalFontSize">
        <Setter Property="FontSize" Value="28"/>
    </Style>
</DockPanel.Resources>

0

让我们来做一些BLACK MAGIC的事情:

  1. 将双重资源添加到您的应用程序资源中
<Application.Resources>
    <sys:Double xmlns:sys="clr-namespace:System;assembly=mscorlib" x:Key="GlobalFontSize">12</sys:Double>
</Application.Resources>
  1. 在您的App类中添加静态属性
public static double GlobalFontSize
{
    get => (double)Current.Resources["GlobalFontSize"];
    set => Current.Resources["GlobalFontSize"] = value;
}
  1. 在任何需要的地方使用此资源 DynamicResource
FontSize="{DynamicResource GlobalFontSize}"
  1. App.GlobalFontSize以任何方式访问属性以更改值,binding都可以!
App.GlobalFontSize = 20;
//Or
{Binding Path=(local:App.GlobalFontSize)}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.