当我注意到一些奇怪的事情时,我一直在尝试使用自定义控件来识别内存泄漏:
Private f = Me.Font
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
If f IsNot Me.Font Then 'ALWAYS TRUE
f.Dispose()
f = Me.Font
End If
...
End Sub
Me.Font 每次都会返回不同的实例,这让我质疑我调用 Me.Font 的其他情况。
通常这没什么大不了的,但在此控件中最多可以每 500 毫秒调用一次绘制。
Me.Font 是否每次调用时都会生成,因此每次都应该处理掉?还有其他类似的控件属性我需要警惕吗?
最佳答案
如果您使用的是从 System.Windows.Forms.Control
继承的控件,并且未更改当前字体或默认字体 其中,这似乎很合乎逻辑。
如果我们看一下Microsoft's Reference Source对于 .NET Framework,我们可以看到 Control.Font
property最初尝试获取控件的当前字体:
Font font = (Font)Properties.GetObject(PropFont);
if (font != null) {
return font;
}
如果没有当前字体(如果其 null
或 Visual Basic 中的 Nothing
),它将尝试获取其父字体:
Font f = GetParentFont();
if (f != null) {
return f;
}
现在,如果控件没有父控件,GetParentFont()
将返回 null
(这可能会一直返回,直到到达父窗体)。如果到达最后一个父级 GetParentFont()
将返回 null
,从而使执行继续。由于该控件不是 ActiveX 控件,因此 if (IsActiveX)
检查将失败并继续:
AmbientProperties ambient = AmbientPropertiesService;
if (ambient != null && ambient.Font != null) {
return ambient.Font;
}
我不确定这会做什么,但如果检查失败,我们就会进入有趣的部分:
return DefaultFont;
该控件返回 DefaultFont
属性,并且如果我们 go to its code :
if (defaultFont == null) {
defaultFont = SystemFonts.DefaultFont;
Debug.Assert(defaultFont != null, "defaultFont wasn't set!");
}
return defaultFont;
我们可以看到它检查控件是否已经定义了自己的默认字体,如果没有,它将返回所有标准控件的默认字体(通过 SystemFonts.默认字体
)。
如果我们最终跳到the code for SystemFonts.DefaultFont
我们可以看到它将创建一个名为 defaultFont
的变量,并最终返回该变量。
Font defaultFont = null;
现在,当查看变量的分配方式时,我们可以看到它总是创建一个新的 Font
实例(这将是导致您的问题的原因):
//Each line represents an example taken from the code.
defaultFont = new Font("MS UI Gothic", 9);
defaultFont = new Font("Tahoma", 8); //This appears two times.
defaultFont = new Font(FontFamily.GenericSansSerif, 8);
defaultFont = FontInPoints(defaultFont);
//FontInPoints only have one line: "return new Font(...);"
因此我们现在可以得出结论,每次您调用 YourControl.Font
时,它都会返回一个新的 Font
实例如果您没有这样做的话分配自定义字体/自定义默认字体,如果所有其他检查失败使其获得 Windows 的默认字体。
关于vb.net - .NET CF Forms - Me.Font - 处理控件默认字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38208482/