css属性改变文本字体_[.NET]更改字体的属性

css属性改变文本字体

So, looking to -truly- change the FontFamily of your .NET Font, are you? For whatever reason, I've seen this problem confronted and abandoned several times now. Because of this, I decided to delve into the issue, and finally came out with a solution using Reflection. It's actually rather simple.

因此,想要真正更改.NET字体的FontFamily,对吗? 无论出于何种原因,我已经看到这个问题现在面临并被放弃了好几次。 因此,我决定深入研究这个问题,并最终提出了使用Reflection的解决方案。 实际上很简单。

Because the System.Drawing.Font class is sealed, we can't inherit from it, so there goes that possiblity. On top of that, there is no interface or anything (that I know of) that can offer the same versatile functionality--all the System.Windows.Forms.Control deriven classes require a Font for the Font property.

由于System.Drawing.Font类是密封的,因此我们无法从其继承,因此可以实现这种可能性。 最重要的是,没有可以提供相同通用功能的界面或任何东西(我知道)—全部为System.Windows.Forms.Contr 所有派生类都需要Font属性的Font。

On top of this fact, all of the Font object's properties are get-only (aka, read-only; the "set" accessor has been omitted), and there is no method used to substitute this functionality. However, using an extremely invaluable tool, I've found that the Font class internally implements a small number of methods that may be used to aid us in the process. The problem is, these methods are private. To invoke a private method or "mess with" a private field, there are a couple steps we have to take.

最重要的是,所有Font对象的属性都是只读的(又名只读;省略了“设置”访问器),并且没有任何方法可以替代此功能。 但是,使用极其宝贵的工具,我发现Font类在内部实现了少量方法,这些方法可用于帮助我们进行此过程。 问题是,这些方法是私有的。 要调用私有方法或与私有字段“混淆”,我们需要采取几个步骤。

First, get an instance of the Font Type (System.Type) through the typeof operator, like the following.

首先,通过typeof运算符获取Font Type(System.Type)的实例,如下所示。

//C#
Type fontType = typeof(Font);
//MC  
Type^ t = Font::typeid;

Through this Type object, we can invoke any method or change any member of the Font type, given an instance to apply the change or invocation to. There are private fields within the Font type, with the following names (I'll give descriptions, as well). I'll only highlight the important ones:

通过此Type对象,我们可以调用任何方法或更改Font类型的任何成员,给定实例来应用更改或调用。 在Font类型中有一些私有字段,具有以下名称(我也会提供描述)。 我只强调重要的那些:

fontFamily : FontFamily - Represents the managed wrapper of the Font's FontFamily.

fontFamily:FontFamily-表示Font的FontFamily的托管包装。

fontSize : Single - The size in of the font, measured in whatever the private fontUnit field is.

fontSize:Single-字体的大小,以私有fontUnit字段的大小为单位。

fontStyle : FontStyle - The FontStyle value of the font.

fontStyle:FontStyle-字体的FontStyle值。

fontUnit : GraphicsUnit - The GraphicsUnit value used to size the font.

fontUnit:GraphicsUnit-用于调整字体大小的GraphicsUnit值。

gdiCharSet : Byte - Unimportant; usually is a value of 1.

gdiCharSet:字节-不重要; 通常为1。

gdiVerticalFont : Boolean - True for vertical; otherwise, false.

gdiVerticalFont:Boolean-垂直为true; 否则为假。

nativeFont : IntPtr - Handle to the FontFamily's native Font (accessed through the FontFamily's internal instance property "NativeHandle")

nativeFont:IntPtr-处理FontFamily的本机字体(通过FontFamily的内部实例属性“ NativeHandle”访问)

The rest are as follows, and are (up until this point, I believe) not useful:

其余的如下,并且(到目前为止,我认为)没有用:

LogFontCharSetOffset : Int32

LogFontCharSetOffset:Int32

LogFontNameOffset : Int32

LogFontNameOffset:Int32

originalFontName : String

originalFontName:字符串

systemFontName : String

systemFontName:字符串

Now, on to actually changing the font's properties. To change any of the fields (except the fontFamily and nativeFont fields, which I will go into in a minute) in the Font, you simple use the following method call, or something like it:

现在,开始实际更改字体的属性。 要更改字体中的任何字段(除了fontFamily和nativeFont字段,我将在稍后介绍),只需使用以下方法调用或类似的方法即可:

//C#:
typeof(Font).InvokeMember("fieldName", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, fontInstanceToModify, new Object[] { /*Value to assign*/ });
 
//MC  :
Font::typeid->InvokeMember(L"fieldName", BindingFlags::NonPublic | BindingFlags::Instance | BindingFlags::SetField, nullptr, fontInstanceToModify, gcnew cli::array<Object^>^ { /*Value to assign*/ });

For example, to change the Size to 16, you could do the following.

例如,要将大小更改为16,可以执行以下操作。

// C#:
typeof(Font).InvokeMember("fontSize", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, fontInstanceToModify, new Object[] { 16f });
 
// MCPP:
Font::typeid->InvokeMember(L"fontSize", BindingFlags::NonPublic | BindingFlags::Instance | BindingFlags::SetField, nullptr, fontInstanceToModify, gcnew cli::array<Object^>^ { 16.0f });

That should work for any of the items (except nativeFont and fontFamily, which might cause problems if you do this) in the FIRST list above (the second list is something I haven't experimented with, though it is there for your reference). So, how do we change the FontFamily, and what's up with the nativeFont field, too? They actually go hand in hand. When a GDI+ method is called, a handle to the Font, and the font's Native

上面的FIRST列表中的任何项目(nativeFont和fontFamily除外,如果您这样做可能会引起问题)都应该起作用(第二个列表是我没有尝试过的东西,尽管它可供您参考)。 那么,我们如何更改FontFamily,nativeFont字段又如何处理? 他们实际上并驾齐驱。 调用GDI +方法时,将显示字体的句柄和字体的本机

FontFamily handle must be passed, so simply changing one or the other just does not suffice. Getting the handle to a native font is kind of a pain, and involves a few API calls, but luckily, the .NET Framework left us a nice little present we can use to get the handle anyway.This method actually takes care of all of the nativeFont portion just on invocation, so all we need to do is make sure that we've changed the FontFamily beforehand. We could just change the field, but we'd probably have to do more API calls and such, and we don't want that. Instead, call the private method called "SetFontFamily"*, which takes a single FontFamily as a parameter and returns void, like this:

必须传递FontFamily句柄,因此仅更改其中一个是不够的。 获取本机字体的句柄有点麻烦,并且涉及一些API调用,但是幸运的是,.NET Framework给我们留下了一个不错的礼物,无论如何我们都可以使用该句柄。 nativeFont部分只是在调用时,因此我们需要做的就是确保我们事先更改了FontFamily。 我们可以只更改字段,但是可能不得不做更多的API调用,而我们不希望那样做。 而是调用名为“ SetFontFamily” *的私有方法,该方法将单个FontFamily作为参数并返回void,如下所示:


// C#:
typeof(Font).InvokeMember("SetFontFamily", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, fontInstanceToModify, new Object[] { yourNewFontFamily });
 
// MC  :
Font::typeid->InvokeMember(L"SetFontFamily", BindingFlags::NonPublic | BindingFlags::Instance | BindingFlags::InvokeMethod, nullptr, fontInstanceToModify, gcnew cli::array<Object^>^ { yourNewFontFamily });

However, this isn't quite enough, as the NativeFont handle doesn't get updated unfortunately. This is quickly solved by invoking a simple parameterless void-returning method called "CreateNativeFont". A call to this method would look like the following.

但是,这还不够,因为遗憾的是NativeFont句柄没有得到更新。 通过调用一个简单的无参数的空返回方法“ CreateNativeFont”,可以快速解决此问题。 对该方法的调用如下所示。

// C#
typeof(Font).InvokeMember("CreateNativeFont", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, fontInstanceToModify, null);
 
// MC  :
Font::typeid->InvokeMember(L"CreateNativeFont", BindingFlags::NonPublic | BindingFlags::Instance | BindingFlags::InvokeMethod, nullptr, fontInstanceToModify, nullptr);

Yeup, that's it. Just remember that if you change the FontFamily of your font (whether it be thorugh the method SetFontFamily or changing the field directly), you need to call CreateNativeFont sometime afterward (as long as you do so before using the font).

是的,就是这样。 只要记住,如果您更改了字体的FontFamily(无论是通过SetFontFamily方法还是直接更改字段),那么之后都需要调用CreateNativeFont(只要在使用字体之前这样做即可)。

There is yet another thing to look out for, however: many fonts don't actually support a lot of the FontStyle values (including Regular!). I suggest you use the instance method FontFamily.IsStyleSupported(FontStyle) to determine this when changing fonts like I've shown; be sure to change to a supported FontStyle.

但是,还需要注意另一件事:许多字体实际上并不支持很多FontStyle值(包括Regular!)。 我建议您使用实例方法FontFamily.IsStyleSupporte d(字体样式 e)在更改如我所示的字体时确定这一点; 确保更改为受支持的FontStyle。

Lastly, for the impatient and/or lazy ones, I've included the real beauty in this article below. You can import the methods directly into your code, if you wish. It may even be a good idea to create your own customizeable Font with a Font object as a private field (make it implicitly convertible to a Font to "fake" inheritance, because Font is sealed).

最后,对于那些急躁和/或懒惰的人,我在下面的文章中包括了真正的美丽。 如果愿意,可以将方法直接导入代码中。 使用Font对象作为私有字段创建自己的可自定义Font甚至是一个好主意(因为它是密封的,因此可以隐式转换为Font以实现“假”继承)。

C#:

C#:

public static void SetFontFamily(this Font myFont, FontFamily myFamily
{
    typeof(Font).InvokeMember("SetFontFamily", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, 
          myFont, new Object[] { myFamily });
     typeof(Font).InvokeMember("CreateNativeFont", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, 
          myFont, null);
}
public static void SetSize(this Font myFont, Single mySize)
{
     typeof(Font).InvokeMember("fontSize", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, myFont,
          new Object[] { mySize });
}
// Returns false if style wasn't supported
public static Boolean SetFontStyle(this Font myFont, FontStyle myStyle)
{
     if(myFont.FontFamily.IsStyleSupported(myStyle))
     {
          typeof(Font).InvokeMember("fontSize", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField, null, myFont,
               new Object[] { mySize });
          return true;
     }
     return false;
}

Hope this has helped, or at least been an interesting read!

希望这有所帮助,或者至少是有趣的阅读!

Nate

内特

*You can probably just change the field directly, but I would just invoke the method anyway.

*您可能可以直接更改字段,但是无论如何我都将调用该方法。

翻译自: https://www.experts-exchange.com/articles/1011/NET-Change-a-Font's-properties.html

css属性改变文本字体

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值