问题
I have label with custom font and timer which change value in label. My app start minimzed. When I displaying the app sometimes exception is displayed and insted of text in label is red cross.
here I try call async method for label text change
private void timer1_Tick(object sender, EventArgs e)
{
// create a delegate of MethodInvoker poiting to showTime function.
MethodInvoker simpleDelegate = new MethodInvoker(showTime);
// Calling showTime Async
simpleDelegate.BeginInvoke(null, null);
}
font loading
public Form1()
{
InitializeComponent();
SystemEvents.SessionSwitch += new SessionSwitchEventHandler(SystemEvents_SessionSwitch); //event handler for windows lock
File.WriteAllBytes(appPath + "\\font.ttf", Resources.font); //copy font from resources
try
{
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(appPath + @"/font.ttf");
label1.Font = new Font(pfc.Families[0], 11, FontStyle.Bold);
}
catch
{
MessageBox.Show("Failed to load nice font." + "\r\n" + "Using standart font instead.", "Time app", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
here is method for label tet change
private void showTime()
{
label1.Text = time.ToString();
}
***** Exception Text *******
System.ArgumentException: Parameter is not valid.
at System.Drawing.FontFamily.GetName(Int32 language)
at System.Drawing.FontFamily.get_Name()
at System.Windows.Forms.Internal.WindowsFont.FromFont(Font font, WindowsFontQuality fontQuality)
at System.Windows.Forms.Internal.WindowsGraphicsCacheManager.GetWindowsFont(Font font, WindowsFontQuality fontQuality)
at System.Windows.Forms.TextRenderer.MeasureText(String text, Font font, Size proposedSize, TextFormatFlags flags)
at System.Windows.Forms.Layout.LayoutUtils.MeasureTextCache.GetUnconstrainedSize(String text, Font font, TextFormatFlags flags)
at System.Windows.Forms.Layout.LayoutUtils.MeasureTextCache.TextRequiresWordBreak(String text, Font font, Size size, TextFormatFlags flags)
at System.Windows.Forms.Label.CreateTextFormatFlags(Size constrainingSize)
at System.Windows.Forms.Label.CreateTextFormatFlags()
at System.Windows.Forms.Label.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Label.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Question: how get rid of this exception when Im using custom font?
回答1:
The problem is that the PrivateFontCollection
instance in the pfc
variable goes out of scope, and sometimes gets collected before the control is drawn for the first time (which seems to acquire a strong reference to the instance afterwards).
Move the instance outside the method to prevent GC from collecting it:
class Form1 : Form
{
readonly PrivateFontCollection _pfc = new PrivateFontCollection();
public Form1()
{
...
_pfc.AddFontFile(appPath + @"/font.ttf");
...
}
}
回答2:
Here is an example that was used in another question on here. It shows what you need. http://www.bobpowell.net/embedfonts.htm
来源:https://stackoverflow.com/questions/11829344/parameter-is-not-valid-when-draw-text-in-label-with-custom-font