WPF 类比“em”; 单元

发布于 2024-07-14 18:05:28 字数 112 浏览 13 评论 0原文

CSS em 单位的 WPF 类比是什么?

What is the WPF analogy for the CSS em unit?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

最冷一天 2024-07-21 18:05:28

这就是我所做的。 创建了一个 MarkupExtension,它根据 Window 上分配的字体将字体大小转换为 EM。

我想要感谢
http:// /10rem.net/blog/2011/03/09/creating-a-custom-markup-extension-in-wpf-and-soon-silverlight

http://tomlev2.wordpress.com/tag/markup-extension/

用于提供所需的知识。

[MarkupExtensionReturnType(typeof(double))]
public class EmFontSize : MarkupExtension
{
    public EmFontSize() { }

    public EmFontSize(double size)
    {
        Size = size;
    }

    [ConstructorArgument("size")]
    public double Size { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (serviceProvider == null)
            return null;

        // get the target of the extension from the IServiceProvider interface
        IProvideValueTarget ipvt = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
        if (ipvt.TargetObject.GetType().FullName == "System.Windows.SharedDp")
            return this;

        DependencyObject targetObject = ipvt.TargetObject as DependencyObject;

        var window = TryFindParent<Window>(targetObject);
        if (window != null)
        {
            return window.FontSize * Size;
        }
        return 12 * Size;
    }

    public static T TryFindParent<T>(DependencyObject child) where T : DependencyObject
    {
        //get parent item
        DependencyObject parentObject = GetParentObject(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
        {
            return parent;
        }
        else
        {
            //use recursion to proceed with next level
            return TryFindParent<T>(parentObject);
        }
    }

    public static DependencyObject GetParentObject(DependencyObject child)
    {
        if (child == null) return null;

        //handle content elements separately
        ContentElement contentElement = child as ContentElement;
        if (contentElement != null)
        {
            DependencyObject parent = ContentOperations.GetParent(contentElement);
            if (parent != null) return parent;

            FrameworkContentElement fce = contentElement as FrameworkContentElement;
            return fce != null ? fce.Parent : null;
        }

        //also try searching for parent in framework elements (such as DockPanel, etc)
        FrameworkElement frameworkElement = child as FrameworkElement;
        if (frameworkElement != null)
        {
            DependencyObject parent = frameworkElement.Parent;
            if (parent != null) return parent;
        }

        //if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
        return VisualTreeHelper.GetParent(child);
    }
}

使用示例

xmlns:my="clr-namespace:FontSizeExample"
<TextBlock Text="Sample Font" FontSize="{my:EmFontSize 1.1}"/>
<TextBlock Text="Sample Font" FontSize="{my:EmFontSize .9}"/>

Here is what I did. Created a MarkupExtension that converts Font size to EM based on font assigned on Window.

I would like to thank
http://10rem.net/blog/2011/03/09/creating-a-custom-markup-extension-in-wpf-and-soon-silverlight

and

http://tomlev2.wordpress.com/tag/markup-extension/

for providing required knowledge.

[MarkupExtensionReturnType(typeof(double))]
public class EmFontSize : MarkupExtension
{
    public EmFontSize() { }

    public EmFontSize(double size)
    {
        Size = size;
    }

    [ConstructorArgument("size")]
    public double Size { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (serviceProvider == null)
            return null;

        // get the target of the extension from the IServiceProvider interface
        IProvideValueTarget ipvt = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
        if (ipvt.TargetObject.GetType().FullName == "System.Windows.SharedDp")
            return this;

        DependencyObject targetObject = ipvt.TargetObject as DependencyObject;

        var window = TryFindParent<Window>(targetObject);
        if (window != null)
        {
            return window.FontSize * Size;
        }
        return 12 * Size;
    }

    public static T TryFindParent<T>(DependencyObject child) where T : DependencyObject
    {
        //get parent item
        DependencyObject parentObject = GetParentObject(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
        {
            return parent;
        }
        else
        {
            //use recursion to proceed with next level
            return TryFindParent<T>(parentObject);
        }
    }

    public static DependencyObject GetParentObject(DependencyObject child)
    {
        if (child == null) return null;

        //handle content elements separately
        ContentElement contentElement = child as ContentElement;
        if (contentElement != null)
        {
            DependencyObject parent = ContentOperations.GetParent(contentElement);
            if (parent != null) return parent;

            FrameworkContentElement fce = contentElement as FrameworkContentElement;
            return fce != null ? fce.Parent : null;
        }

        //also try searching for parent in framework elements (such as DockPanel, etc)
        FrameworkElement frameworkElement = child as FrameworkElement;
        if (frameworkElement != null)
        {
            DependencyObject parent = frameworkElement.Parent;
            if (parent != null) return parent;
        }

        //if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
        return VisualTreeHelper.GetParent(child);
    }
}

Sample Usage

xmlns:my="clr-namespace:FontSizeExample"
<TextBlock Text="Sample Font" FontSize="{my:EmFontSize 1.1}"/>
<TextBlock Text="Sample Font" FontSize="{my:EmFontSize .9}"/>
我还不会笑 2024-07-21 18:05:28

em 大小是当前字体中大写字母 M 的宽度,Wpf 中没有依赖于字体的大小调整方法

Btw,WPF 使用始终为 1/96 英寸的“设备独立像素”(因为这是今天的一个像素)显示器)所以:

  • 1 像素为 1/96 英寸
  • 96 像素为一英寸
  • 1.33333 像素为一个点
  • 3.779 像素为一毫米

这些在显示器上非常不准确,因为几乎所有显示器都报告 96DPI 分辨率并忽略实际像素大小,但它们非常不准确。打印时很有用。

em size is the width of the uppercase letter M in the current font, there is no font-dependent sizing method in Wpf

Btw, WPF uses "device independent pixels" that are always 1/96 of an inch (because that's one pixels on today's monitors) so:

  • 1 pixel is 1/96 inches
  • 96 pixels in an inch
  • 1.33333 pixels is a point
  • 3.779 pixels is a mm

Those are extremely inaccurate on monitors because almost all monitors report a 96DPI resolution and ignore the real pixel size, but are very useful when printing.

淡淡離愁欲言轉身 2024-07-21 18:05:28
<ScaleTransform ScaleX="1.2" ScaleY="1.2"></ScaleTransform> 

似乎或多或少是 1.2em 的替代品。

<ScaleTransform ScaleX="1.2" ScaleY="1.2"></ScaleTransform> 

seems to be more or less the 1.2em alternative.

明媚殇 2024-07-21 18:05:28

AFAIK,现在还没有。 但是您可以表达您的愿望 这里

一种替代方案(我也不知道这是否可行)是测量所需字体有多大,然后将其作为“ems”单位,然后使用这些“单位”进行缩放。

AFAIK, there isn't one right now. But you can make your desire for this known here.

One alternative (and I don't know if this is possible either) would be to measure how big the desired font is, then take that as your "ems" unit, then scale using those "units" instead.

錯遇了你 2024-07-21 18:05:28

不幸的是,WPF 中没有 em 单位的等效项。 所有字体大小等始终以像素为单位设置。

Unfortunately, there is no equivalent in WPF of the em unit. All your font sizes, etc are always set in Pixels.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文