(WPF) 如何从 ResourceDictionary 将 sys:Double 的值设置为 SystemFonts.MessageFontSize?

Posted

技术标签:

【中文标题】(WPF) 如何从 ResourceDictionary 将 sys:Double 的值设置为 SystemFonts.MessageFontSize?【英文标题】:(WPF) How to set value of a sys:Double to SystemFonts.MessageFontSize from ResourceDictionary? 【发布时间】:2011-01-10 20:13:24 【问题描述】:

场景:

我想为我的 WPF 应用程序使用 3 种标准字体大小:BigFontSizeNormalFontSizeSmallFontSize。这些是双精度值,它们在资源字典中被定义为(sys 被适当定义):

<sys:Double x:Key="BigFontSize">18</sys:Double>
<sys:Double x:Key="NormalFontSize">14</sys:Double>
<sys:Double x:Key="SmallFontSize">12</sys:Double>

这很好用。但我随机选择了 14 作为正常尺寸。我想要的是为NormalFontSize 获得系统定义的字体大小。 (如果完成了,我可以使用转换器as described here 得到BigFontSizeSmallFontSize 相对于NormalFontSize

线索:

我从文档中发现默认字体大小存储在静态属性(双精度)SystemFonts.MessageFontSize 中。但是我应该怎么做才能将该值检索到资源字典? (我知道BindingDynamicResource 不能应用。但是,嘿,这是一个静态值,那么我该如何应用StaticResourcex:Static 或其他什么?)

我试过了

<sys:Double x:Key="XXXFontSize">
    <StaticResource ResourceKey="SystemFonts.MessageFontSize" />
</sys:Double>

<sys:Double x:Key="XXXFontSize">
    <x:Static ResourceKey="SystemFonts.MessageFontSize" />
</sys:Double>

这两个似乎都不起作用(如预期的那样)。我收到一条错误消息,提示 Cannot add content to object of type 'System.Double'.

注意:

我不想从代码中执行此操作,例如从 App()。 (是否可以为 ResourceDictionary 提供代码隐藏?)

我不想将其封装为可以派生其他样式的通用样式(使用BasedOn),因为我有多个资源字典,并且无法将DynamicResourceBasedOn 一起使用 也就是说,我不能使用

<Style x:Key="BigFont" TargetType="x:Type Control">
    <Setter Property="Control.FontSize" 
            Value="Binding Source=x:Static SystemFonts.MessageFontSize,
                            Converter= . . . " />
</Style>

因为,如果我在其他 ResourceDictionary 中有一个样式,比如 HeaderTextBlockStyle,那么我将不得不使用 BasedOn=DynamicResource BigFont,这是不可能的(我认为)

任何帮助将不胜感激。 谢谢。

标签:WPF SystemFonts.MessageFontSize ResourceDictionary FontSize BasedOn DynamicResource

【问题讨论】:

【参考方案1】:

看看这篇文章:Override default styles它可能有你要找的东西。

【讨论】:

感谢 Joshua,您的快速回复!这篇文章很有趣,但它并没有完全解决我的问题。我知道我们可以“覆盖”默认样式,但我想要的是保留默认 FontSize 并将其存储到资源(double 类型)中,以便它可以用于计算其他双资源的相对值(即使这似乎是我的下一个问题!) 嗯,嗯,我能想到的一件事是更改您的代码以使用转换器。然后,您可以将 Control.FontSize 设置为一个转换器对象,该对象在逐个控件的基础上进行评估。看看这个***.com/questions/312044/… 它可能会提供一个替代方案。它不完全在资源中,但可以让你做你想做的事情。 你的意思是我应该将每个控件的字体属性绑定到SystemFonts.MessageFontSize 和一个转换器(假设FontSizeMapper),它接受参数BNS(对于大, Normal 和 Small) 并相应地返回字体大小?是的,这是一个选项,但是如果我不使用 BasedOn=... 将其封装在控件样式中(如我的问题 Note#2 中所述),您不认为这会有点容易吗? 我的想法更像是设置您的样式 FontSize 属性以使用转换来获取值。当然,我假设您具有某种全局价值,可以说我想将所有内容转换为大、小等,这不仅仅是为了个人控制。这样,您可以从转换器访问更多系统级变量,并让转换器确定放在那里的内容。如果有机会,我会看看是否可以将样本放在一起并将其发布到我原来的 cmets 中。 好的,我收回它并不像我想象的那么清楚。我能看到的唯一可行的选择是覆盖默认值。您可以通过资源字典完成此操作。因此,为您想要的每种大小都有一个字典,然后合并正确的一个。查看在运行时切换 WPF 主题/资源字典以了解总体思路。我认为这可能是您完成此任务的最简单方法。【参考方案2】:

我已经这样做了......

public partial class GlobalResources : ResourceDictionary

    public GlobalResources()
    
        this.Add("GiantFontSize", SystemFonts.MessageFontSize * 2.5);
        this.Add("BigFontSize", SystemFonts.MessageFontSize * 1.5);
        this.Add("MediumFontSize", SystemFonts.MessageFontSize * 1.25);
        this.Add("NormalFontSize", SystemFonts.MessageFontSize);
        this.Add("SmallFontSize", SystemFonts.MessageFontSize * 0.85);
    

...它就像一个奇迹一样工作!!!我可以在同一个(部分)资源字典或像这样的其他资源字典中使用这些资源......

<Style ...>
    <Setter Property="FontSize"
            Value="DynamicResource MediumFontSize" />

    ...

</Style>

我不知道这是否是“好习惯”(请对此发表评论),我只知道它有效..!!!

【讨论】:

以上是关于(WPF) 如何从 ResourceDictionary 将 sys:Double 的值设置为 SystemFonts.MessageFontSize?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 WPF 打开网页? [复制]

如何将选定的行从一个 wpf 数据网格复制到另一个 wpf 数据网格? [关闭]

Wpf:如何从嵌套的 DataGrid 中绑定 SelectedItem

WPF - 如何从视图而不是视图模型显示自定义异常

如何从同一 WPF 应用程序托管的 WCF 服务调用 WPF 应用程序中的方法?

如何从 WPF 访问 Windows.Devices.Scanners