ToolStripStatusLabel displayed as black box

2019-01-28 07:53发布

问题:

I use StatusStrip that contains ToolStripStatusLabel. OS - Windows 7, framework 2.0. Usually all displayed normal, but sometimes ToolStripStatusLabel looks like black box:

I read that windows bug, but how I can fix it?

回答1:

This is an obscure bug, triggered when you display the form with the Windows toolbar overlapping your StatusStrip. Moving the window away from the toolbar doesn't get the ToolStripItems on the status strip repainted properly. You'll find a bit of background in this forum post. There was a weak promise for a future fix for it, no idea if that ever happened. Probably not if you are running this on Win7.

You'll need to pay more attention to the position of the window, making sure that parts of it don't disappear underneath the toolbar. In general something you'd always consider, extra important as long as this bug doesn't get fixed. If you don't want to nail down the startup position (you ought to, users tend to like a window getting redisplayed where they last moved it) then simply change the form's StartPosition property to "CenterScreen".



回答2:

This bug has never been fixed. It was in framework 2 and is still in framework 4.

The answer from Hans is a copy of the answer in social.msdn.microsoft.com.

But it is not helpful for me because "CenterScreen" does not solve the problem.

The cause of the problem is not the Windows Taskbar. The cause is a bug that does not draw the StatusStrip when the main Form is behind ANY other window at the first moment of drawing the StatusStrip. But this will also happen when you start the new process with Process.Start() from another process and the new process opens behind the window of another process.

I found a much better solution than the one proposed by Microsoft.

First I tried with

statusStrip.Invalidate();

but it does not work. So we need a stronger way to force Windows to redraw the StatusStrip. Important: The redrawing must happen when the Form with the StatusStrip is ALREADY in foreground! This is so easy that I don't understand why Microsoft does not suggest this method.

Timer mi_StatusTimer = new Timer();

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    mi_StatusTimer.Interval = 500;
    mi_StatusTimer.Tick += new EventHandler(OnTimerBugFix);
}

protected override void OnActivated(EventArgs e)
{
    base.OnActivated(e);

    mi_StatusTimer.Start();
}

void OnTimerBugFix(object sender, EventArgs e)
{
    mi_StatusTimer.Stop();

    statusStrip.Hide();
    Application.DoEvents();
    statusStrip.Show();
}