.NET CF Forms - Me.Font - 配置控件默认字体
.NET CF Forms - Me.Font - Disposing Controls Default Font
当我注意到一些奇怪的事情时,我一直在尝试识别自定义控件的内存泄漏:
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 returns 每次都是不同的实例,这让我质疑我调用 Me.Font.
的其他案例
通常这没什么大不了的,但在此控件中最多每 500 毫秒调用一次绘图。
是不是每次调用都会生成Me.Font,所以每次都要处理掉?还有其他像这样的控件属性我需要警惕吗?
如果您正在使用从 System.Windows.Forms.Control
继承的控件并且您没有更改 当前字体 也没有更改 默认字体,这似乎很合乎逻辑。
如果我们看一下 Microsoft's Reference Source for the .NET Framework we can see that the 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()
将 return null
(这可以一直返回到父级窗体)。如果这到达最后一个父 GetParentFont()
将 return null
,从而使执行继续。由于该控件不是 ActiveX 控件,if (IsActiveX)
检查将失败并继续进行:
AmbientProperties ambient = AmbientPropertiesService;
if (ambient != null && ambient.Font != null) {
return ambient.Font;
}
我不确定这是做什么的,但即使检查失败,我们也会进入有趣的部分:
return DefaultFont;
控件return是DefaultFont
属性,如果我们go to its code:
if (defaultFont == null) {
defaultFont = SystemFonts.DefaultFont;
Debug.Assert(defaultFont != null, "defaultFont wasn't set!");
}
return defaultFont;
我们可以看到它检查控件是否已经定义了自己的默认字体,如果没有它将return所有的默认字体标准控件(通过 SystemFonts.DefaultFont
)。
如果我们最终跳转到 the code for SystemFonts.DefaultFont
,我们可以看到它会创建一个名为 defaultFont
的变量,最终会 return。
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
它都会 return 一个新的 Font
实例 如果你没有't 分配了自定义 font/custom 默认字体,并且 如果所有其他检查都失败了 它获得 Windows' 默认字体。
当我注意到一些奇怪的事情时,我一直在尝试识别自定义控件的内存泄漏:
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 returns 每次都是不同的实例,这让我质疑我调用 Me.Font.
的其他案例通常这没什么大不了的,但在此控件中最多每 500 毫秒调用一次绘图。
是不是每次调用都会生成Me.Font,所以每次都要处理掉?还有其他像这样的控件属性我需要警惕吗?
如果您正在使用从 System.Windows.Forms.Control
继承的控件并且您没有更改 当前字体 也没有更改 默认字体,这似乎很合乎逻辑。
如果我们看一下 Microsoft's Reference Source for the .NET Framework we can see that the 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()
将 return null
(这可以一直返回到父级窗体)。如果这到达最后一个父 GetParentFont()
将 return null
,从而使执行继续。由于该控件不是 ActiveX 控件,if (IsActiveX)
检查将失败并继续进行:
AmbientProperties ambient = AmbientPropertiesService;
if (ambient != null && ambient.Font != null) {
return ambient.Font;
}
我不确定这是做什么的,但即使检查失败,我们也会进入有趣的部分:
return DefaultFont;
控件return是DefaultFont
属性,如果我们go to its code:
if (defaultFont == null) {
defaultFont = SystemFonts.DefaultFont;
Debug.Assert(defaultFont != null, "defaultFont wasn't set!");
}
return defaultFont;
我们可以看到它检查控件是否已经定义了自己的默认字体,如果没有它将return所有的默认字体标准控件(通过 SystemFonts.DefaultFont
)。
如果我们最终跳转到 the code for SystemFonts.DefaultFont
,我们可以看到它会创建一个名为 defaultFont
的变量,最终会 return。
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
它都会 return 一个新的 Font
实例 如果你没有't 分配了自定义 font/custom 默认字体,并且 如果所有其他检查都失败了 它获得 Windows' 默认字体。