且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

设置MDI父窗体的界限

更新时间:2023-12-06 09:00:52

好吧,您可以做到,但是……请您帮个大忙:完全不要使用MDI.没有设计,您可以更轻松地实现设计,并且质量更高.即使Microsoft也不鼓励使用MDI,实际上,Microsoft已将其从WPF中删除,并且几乎不支持它.更重要的是,如果您使用MDI,则会吓跑所有用户.只是不要.我可以解释该怎么办.

您在哪里看到会使用MDI且至少是专业的不错的UI?无处.

请参阅:
http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages [在WPF中使用MDI窗口的问题 [ ^ ],
MDIContainer提供错误 [如何在WPF中创建MDI父窗口? [ ^ ] — 韦恩·盖拉德(Wayne Gaylard).

停止折磨自己,追逐您的用户.使用我在上面引用的答案中尝试解释的想法,实现漂亮的选项卡式界面或其他内容,并感到高兴.


—SA
Well, you can do it but… do yourself a great favor: do not use MDI at all. You can do much easier to implement design without it, with much better quality. MDI is highly discouraged even by Microsoft, in fact, Microsoft dropped it out of WPF and will hardly support it. More importantly, you will scare off all your users if you use MDI. Just don''t. I can explain what to do instead.

Where did you see any decent UI which would use MDI and be at least professional? Nowhere.

Please see:
http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages[^] — Wikipedia,
Question on using MDI windows in WPF[^],
MDIContainer giving error[^] — SA,
How to Create MDI Parent Window in WPF?[^] — Wayne Gaylard.

Stop torturing yourself and chase off your users. Use the ideas I tried to explain in my answered referenced above, implement nice tabbed interface or something else and be happy.


—SA


注意:我同意尊敬的同事,指导者SAKruykov的观点,即基于MDI的WinForm应用程序现在不是好习惯.
一些评论:

1.我认为您的问题混淆了子表单的移动调整大小:您不能在表单的右侧或底部移动"表单;您只能调整大小.

一个. ...在正常"情况下,当子窗体完全开始包含在MDI父窗体中时... 您不能在MDI父窗体的边界之外调整MDI子窗体的大小.

b.所以:这里的真正问题必须是:移动子窗体.

C. MDI体系结构中的脏事实"是恕我直言的一个事实,它是:一旦您将MDI子窗体的一部分移到了其MDI父窗体之外,您就可以重新调整它的大小!

2. 您可能还只是碰到了" MDI实现中的另一个真正缺陷:即使您将MDI父表单的"AutoScroll"属性设置为"false": MDI子窗体,使其扩展到父窗体的边界之外:将导致滚动条出现在MDI父窗体上.

因此:如果必须使用MDI,并且要在移动子窗体时将其保留在MID父窗体窗口边界中,该怎么办?

您可以使用子窗体的几个事件
Note: I agree with esteemed colleague, and mentor, SAKruykov, that MDI based WinForm applications are not good practice now.

A few comments:

1. I think your question confuses moving vs. re-sizing of the Child Forms: you can''t "move" a Form by its right or bottom; you can only resize.

a. ... under ''normal'' conditions, when the Child Form starts off completely contained in the MDI Parent Form ... you can''t resize an MDI Child Form outside its MDI Parent boundaries.

b. so: the real issue here must be: moving the Child Form.

c. the "dirty fact" here, a flaw, imho, in MDI architecture, is the fact that: once you have moved part of an MDI Child Form outside its MDI Parent Form, you can re-size it !

2. You also may have just "crashed against" another one of the real flaws in the MDI implementation: even if you set the ''AutoScroll property of the MDI Parent Form to ''false: moving an MDI Child Form so it extends, outside the Parent Forms'' boundaries: will cause scrollbars to appear on the MDI Parent Form.

So: what to do if you must use MDI, and you want to keep the Child Forms in the MID Parent Form window boundaries when you Move them ?

There are several events of the child Form you could possibly use
ClientSizeChanged
LocationChanged
SizeChanged
RegionChanged

这些事件中的任何一个都不公开自定义EventArgument结构,该结构允许您取消其反映的动作.它们都没有公开对称的Begin/End事件对,在"Begin ... Event"中带有"cancel"选项,就像其他一些.NET控件的事件一样.

因此,当子窗体超出MDI父窗体的范围时,您将以某种方式取消移动"的影响,并且上述肮脏事实"使情况变得复杂.

您可以利用此技术来确定MDI子窗体是否完全包含在MDI父窗体中:只要MDI子窗体完全位于MDI父窗体中,则边界矩形的交集(正确导出时)从这两个表单的适当坐标空间中得出),这两个表单将等于子表单的边界矩形(详细信息如下).

因此,在MDI父表单中,这里的名称为"Form1 ...:

None of these Events expose a custom EventArgument structure that would allow you to cancel the action they reflect. None of them expose a symmetric pair of Begin/End events, with a "cancel" option in the ''Begin... Event as some other .NET control''s events do.

So you are going to have, somehow, undo the effect of a Move when the Child Form goes outside the bounds of the MDI Parent Form, and that''s complicated by the "dirty fact" mentioned above.

You can exploit this technique for determining whether the MDI Child Form is, or is not, fully contained in the MDI Parent Form: whenever the MDI Child Form is completely within the MDI Parent Form: then the intersection of the bounding rectangles (when derived correctly from the appropriate co-ordinate space of the two Forms) of those two Forms will be equal to the bounding rectangle of the Child Form (details to follow).

So in the MDI Parent Form ... here named ''Form1 ... :

// create a new MDI Child Form
Form2 f2 = new Form2();

// think about why this must be a public static property !
public static Rectangle MdiParentBounds { get; set; }

private void Form1_Load(object sender, EventArgs e)
{
    f2.MdiParent = this;
    f2.Show();
    // think about why this must be the ClientRectangle here !
    MdiParentBounds = this.ClientRectangle;
}

private void Form1_SizeChanged(object sender, EventArgs e)
{
// think about why this must be the ClientRectangle here !
    MdiParentBounds = this.ClientRectangle;
}Now in the MDI Child Form: ... here named Form2 ...:private Rectangle childBounds;

private Rectangle interSectRect;

private void Form2_LocationChanged(object sender, EventArgs e)
{
    // think about why we use 'Bounds here, and not ClientRectangle !
    childBounds = this.Bounds;

    interSectRect = Rectangle.Intersect(Form1.MdiParentBounds, childBounds);

    if ( interSectRect == childBounds)
    {
        MessageBox.Show("child form is contained");
        // all happy now
    }
    else
    {
        MessageBox.Show("child form is not contained");
        // and now what are you going to do ?
    }
}

这应该为您提供足够的信息和代码,以便能够开始检测MDI子窗体何时超出其MDI父窗体的边界.

将已经超出边界的子窗体"移回边界以使其位于边界内的操作将留给您继续进行.

提示:您将确定子窗体的哪些边"在外部,以及需要使用什么偏移量(垂直和水平方向)将其重新定位.如果在MDI Parent的范围之外,还对其进行了尺寸调整,欢迎进一步并发症!

当然:您可以采用便宜的出路",只需将MDI子窗体的大小更改为您知道适合MDI父窗体的大小,然后将其捕捉回MDI父窗体的左上角:但是,可以肯定的是,您是一个雄心勃勃的程序员,他不会仅仅满足于轻松的出路" :)

***,比尔

This should give you enough information, and code, to get started on being able to detect when an MDI Child Form extends outside the boundaries of its MDI Parent Form.

What you are going to have to do to move the Child Form which has gone outside the boundaries back so that it is within the boundaries, is left for you to go to work on.

Hint: you are going to determine which "edges" of the Child Form are outside, and what offset you need to use, vertically and horizontally, to relocate it back. And if it''s been re-sized also, while outside the MDI Parent''s bounds: welcome to further complications !

Of course: you could take the "cheap way out," and just change the size of the MDI Child Form to be some size you know will fit in the MDI Parent Form, and snap it back to upper-left in the MDI Parent: but, surely, you are an ambitious programmer who won''t just settle for the "easy way out" :)

best, Bill