MDI 子刷新/重画问题(C#、Winforms、.NET 2.0、VS2005、DevExpress 8.2)
你好——我的一个朋友指着你们。
我有一个 MDI 应用程序(C#、Winforms、.NET 2.0、VS2005、DevExpress 8.2),并且我的一个表单的行为非常奇怪 - 在与同一表单类的另一个实例重叠的地方没有正确地重新绘制自身。
这些表单包含一个自定义控件(其中包含各种 DevExpress 控件),并且继承自基本表单(其本身也是继承的)。
由于表单继承的问题(那个老栗子),构造函数中进行了一些控制重新排列。
问题 1(次要):除非调整表单大小,否则此控件重新定位/调整大小似乎都不会生效,因此我在重新排列后将宽度向上和向下微移一个像素。 丑陋、老套,我真的不想这样做。
问题2(主要): 如果显示表单,然后使用 API 调用 SetParent 将其附加到 MDI 表单,则当我显示第二个实例时,两个表单的各个部分在重叠的地方未正确绘制 - 顶部表单的位位于现有表单的后面 - 并且这当表单移动时,问题会变得更糟,导致它们基本上无法使用。 其他不同类型的子表单(如果存在)似乎不受影响...
停止新闻:我已经确定它不必是子表单的 2 个实例。 只有一个仍然存在问题 - 主要是表单的边缘,例如刷新的区域比表单本身小。
如果使用子窗体的 .MDIParent 属性设置父窗体,则不会出现此问题 - 但我们不能这样做,因为窗体可能由非 .Net 应用程序中托管的控件显示。 此外,即使现有子项(不同类型)已最大化,我也需要显示非最大化的子表单,而这仅在使用 SetParent 时发生。
我已经在这种类型的所有表单上尝试过 Refresh() (我有一个保存它们列表的控制器),但没有任何乐趣。 我尝试从具有相同继承结构的基本应用程序中重现这种效果,但我做不到。 显然,这与表单有关 - 因为我昨天从头开始重新创建了表单,但它仍然是相同的,它一定是代码 - 但什么?
我不是形式绘画活动等方面最热门的人,所以我错过了什么吗?
Hiya - been pointed at you guys by a friend of mine.
I have an MDI application (C#, Winforms, .NET 2.0, VS2005, DevExpress 8.2) and one of my forms is behaving very strangely - not repainting itself properly where it overlaps with another instance of the same form class.
The forms contain a custom control (which contains various DevExpress controls), and are inherited from a base form (which is itself inherited).
Due to issues with form inheritance (that old chestnut) there is a bit of control rearranging going on in the constructor.
Problem 1 (minor): None of this control repositioning/resizing seems to take effect unless the form is resized, so I nudge the width up and down by one pixel after the rearranging. Ugly, hacky and I'd really like to not have to do this.
Problem 2 (major):
If forms are shown then attached to the MDI form using the API call SetParent, when I display the 2nd instance, various parts of the two forms are not correctly drawn where they overlap - bits of the top one are behind the existing one - and this problem gets worse when the forms are moved around, rendering them basically unuseable. Other child forms (if present) of a different type seem unaffected...
STOP PRESS: I've established that it doesn't have to be 2 instances of the child form. With only one there are still problems - mainly round the edges of the form, like the area that's being refreshed is smaller than the form itself.
The problem does not occur if the parent is set using the .MDIParent property of the child form - but we cannot do this as the form may be being displayed by a control hosted in a non-.Net application. Also I need to display the child forms non-maximised even if the existing children (of a different type) are maximised, and that only happens using SetParent.
I have tried Refresh() on all the forms of this type (I have a controller that keeps a list of them), but no joy. I have tried to reproduce this effect form a basic app with the same inheritance structure, but I can't. Clearly it is something about the form - since I recreated the form from scratch yesterday and it is still the same it must be the code - but what??
I am not the hottest on form painting events etc. so have I missed something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,这样就可以了。 更改 FormBorderStyle 需要 Windows 窗体从头开始重新创建窗口,现在在 CreateWindowEx() 调用中使用不同的样式标志。 这将使它完全忘记您使用 SetParent() P/Invoke 设置的父级。 还有许多其他属性会导致这种情况发生。 通过重写 OnHandleCreated() 方法进行这些调用,可以避免遇到此类麻烦。
更好的是,通过将所有控件和逻辑放在 UserControl 中,完全避免像 SetParent() 这样麻烦的 API。
Yes, that would do it. Changing the FormBorderStyle requires Windows Forms to recreate the window from scratch, now using different style flags in the CreateWindowEx() call. That would make it completely forget about the parent you set with the SetParent() P/Invoke. There are lots of other properties that causes this to happen. Avoid the kind of trouble you got into by making these calls in an override of the OnHandleCreated() method.
Better yet, avoid troublesome APIs like SetParent() completely by putting all your controls and logic in a UserControl.
啊哈!
在显示表单之前,我正在更改代码中的 FormBorderStyle。 我删除了那条线,问题就消失了......
这对我来说就足够了。 :-)
Ah ha!
I was changing the FormBorderStyle in code before showing the form. I removed that line and the problem went away...
That'll do for me. :-)
我知道这是一个旧线程,但我所做的事情为我解决了这个问题。 这可能会帮助有类似问题的人。
我的问题:
我们有一个应用程序,其中将两个外部应用程序嵌入到由拆分器分隔的父窗口中。 它用于并排显示两个应用程序的信息。 我们面临的问题是两个子窗口在父窗口上绘制得很好(使用 SetParent、SetWindowLong 和 MoveWindow),但是在子窗口中移动或执行操作时,它们会出现绘制/刷新问题(更具体地说) ,父面板将绘制在子窗口上)
在阅读了大量有关嵌入窗口、SetParent 问题的文章后,MSDN 页面 http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx 给了我一个线索。
解决方案:
当使用 SetWindowLong(设置样式)时,请使用 WS_CLIPCHILDREN 样式 -
该样式的作用是防止父窗口重新绘制子窗口占用的区域。 这为我彻底解决了这个问题。
I know this is an old thread, but something I did fixed the issue for me. This might help someone with a similar problem.
My problem:
We have an application in which we embed two external applications in a parent window separated by a splitter. Its used for displaying information from the two applications side by side. The problem we were facing was that the two child windows were getting drawn on the parent window just fine (using SetParent, SetWindowLong and MoveWindow), but while moving or performing operations in the child windows, they would have paint / refresh issues (more specifically, the parent panel would get drawn over the child windows)
After reading tons of articles about embedding windows, SetParent problems, the MSDN page http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx gave me a clue.
Solution:
When using SetWindowLong (to set styles) use the WS_CLIPCHILDREN style -
What this style does is it prevents the parent window from re-drawing the area occupied by the child windows. This resolved the issue completely for me.