Parameter is not valid when draw text in label wit

2019-07-16 18:43发布

问题:

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