C#.NET MDI错误,以编程方式隐藏并再次显示最大化的子窗体,并且最大化后,子窗体的图标无法更改 [英] C#.NET MDI bugs when programmatically hiding and showing again a maximized child form and when maximized, child form's icon cannot be changed

查看:36
本文介绍了C#.NET MDI错误,以编程方式隐藏并再次显示最大化的子窗体,并且最大化后,子窗体的图标无法更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我在使用C#.NET MDI时遇到两个问题.您可以在,其中介绍了操作方法.

在挂起绘画后,您需要调用控件的UpdateBounds方法,并将ClientRectangle Width或Height加1,然后再将其减小到以前的值.这将调用布局功能,使所有内容都可以更新/重新绘制.最后一步是启用绘画.我猜这不是一个很好的解决方案,但是可以.

  StopDrawing();UpdateBounds(Location.X,Location.Y,Width,Height,ClientRectangle.Width,ClientRectangle.Height +1);UpdateBounds(Location.X,Location.Y,Width,Height,ClientRectangle.Width,ClientRectangle.Height-1);StartDrawing(); 


我发现暂停绘画不仅对解决这两个错误很有帮助,而且总体而言还可以使GUI更加流畅地工作.我想这可以帮助消除任何闪烁.但是,此解决方案需要P/Invokes,一般应避免使用.

Basically I am having two problems with C#.NET MDI. You can download VS2010 solution which reproduces bugs here.

1) When programmatically hiding and showing again a maximized child form, it is not maximized properly again and becomes neither maximized or in normal state.

childForm = new Form();
childForm.Text = "Child Form";
childForm.MdiParent = this;

...

private void showButton_Click(object sender, EventArgs e)
{
    childForm.Visible = true;
}

...

private void hideButton_Click(object sender, EventArgs e)
{
    childForm.Visible = false;
}

When child form is maximized, then programicaly hidden and shown again, it becomes something like this (please notice the menu bar - child form's control box appears, but child form is not maximized):

At this stage, child form cannot be moved around. However, I found a workaround for that, simply by showing and hiding a dummy child form, which forces the actual child form to become properly maximized. But this makes MDI area to flicker. Tried Invalidate, Refresh, Update methods, but they don't help. Maybe there are other workarounds to overcome this bug and not to make MDI area flicker with dummy child form?

private void workaround1Button_Click(object sender, EventArgs e)
{
    dummyForm.Visible = true;
    dummyForm.Visible = false;
}

2) When child form is maximized, the icon of the child form is displayed on menu bar. However, if you have to change the icon while the child form is maximized, the icon on the menu bar is not being refreshed (see the image above). I found a workaround for that too, which basically hides and shows menu bar. Icon gets refreshed, but it makes everything below menu bar to flicker. Tried Invalidate, Refresh, Update methods, but they don't help. Is there any other way to make menu bar to refresh the child form's icon?

private void workaround2Button_Click(object sender, EventArgs e)
{
    menuStrip.Visible = false;
    menuStrip.Visible = true;
}


Also I noticed that when parent form is in normal window state mode (not maximized) and you change the width or height of the form by 1 pixel, child form becomes maximized as it should be and child form's icon on menu bar gets refreshed properly and you don't need other workaround I described above. If I change the size of the form programicaly, form flickers by 1 pixel and I cannot do that, when parent form is maximized. Is there any way how I could invoke the repaint/refresh functionality which is called when you resize a form and which makes child form become maximized properly and the icon on the menu bar refreshed?

解决方案

Found a way how to come around those bugs.

First of all you need to suspend painting for a form and its children. I found a very helpful thread here, which describes how to do it.

After suspending painting, you need call UpdateBounds method of the control and increase ClientRectangle Width or Height by one and then decrease it back to the same value it was before. This invokes layout functionality which makes everything to update/repaint. Last step is to enable painting. Not very nice solution I guess, but it works.

StopDrawing();
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height + 1);
UpdateBounds(Location.X, Location.Y, Width, Height, ClientRectangle.Width, ClientRectangle.Height - 1);
StartDrawing();


I find suspending painting very helpful not only for working around those two bugs, but also in general to make GUI work more smoothly. I guess this can help to remove any kind of flickering. However, this solution requires P/Invokes, which should be avoided in general.

这篇关于C#.NET MDI错误,以编程方式隐藏并再次显示最大化的子窗体,并且最大化后,子窗体的图标无法更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆