C# 如何安排MDI子项,使其完全包含在父项中?

C# 如何安排MDI子项,使其完全包含在父项中?,c#,.net,winforms,mdi,C#,.net,Winforms,Mdi,我需要订购矩形窗口。这意味着当我有六个窗口时,它以矩形2x3排列,当我有五个窗口时,它以矩形2x3排列,但没有最后一个窗口,当我有9个窗口时,它以3x3排列。但我在坐标方面遇到了一些问题-子窗口超出了父窗口的范围。(img) 我在java上使用了与mdi应用程序相同的算法 for(int i=0;i<a;i++) for(int j=0;j<b;j++) try{ indfr.get(counter).setLocation(i*t

我需要订购矩形窗口。这意味着当我有六个窗口时,它以矩形2x3排列,当我有五个窗口时,它以矩形2x3排列,但没有最后一个窗口,当我有9个窗口时,它以3x3排列。但我在坐标方面遇到了一些问题-子窗口超出了父窗口的范围。(img)

我在java上使用了与mdi应用程序相同的算法

for(int i=0;i<a;i++)
    for(int j=0;j<b;j++)
         try{
             indfr.get(counter).setLocation(i*theDesktop.getWidth()/a,j*theDesktop.getHeight()/b);
             indfr.get(counter).setSize(theDesktop.getWidth()/a,theDesktop.getHeight()/b);
             counter++;
            }catch (IndexOutOfBoundsException exc){ break;}
其中list-
Form[]list=this.MdiChildern

坐标有什么问题? (注:这不是完整的算法,但它是windows排序的主循环)


问题行是
try
块中的问题行:

list[counter].SetDesktopLocation(i*list[counter].MdiParent.Width/a, j*list[counter].MdiParent.Height/b);
list[counter].Size = new Size(list[counter].MdiParent.Width/a, list[counter].MdiParent.Height/b);
counter++;
您正在检查
Form.Width
Form.Height
,它们返回屏幕上表单的总大小,包括所有边框。您只能将子窗口放置在父窗体的客户端区域内,因此需要查询。定义为表单的大小,减去边框和标题栏;换句话说,可以放置孩子的形状区域

试着
块重新写入以下内容:

list[counter].SetDesktopLocation(i*list[counter].MdiParent.ClientSize.Width/a, j*list[counter].MdiParent.ClientSize.Height/b);
list[counter].Size = new Size(list[counter].MdiParent.ClientSize.Width/a, list[counter].MdiParent.ClientSize.Height/b);
counter++;
然后扔掉那个愚蠢的空
catch
块。如果抛出异常时所做的一切都是
break
ing,那么捕获异常就没有意义了。它将冒泡到下一个异常处理程序,如果需要,一直到全局异常处理程序。只捕获您专门知道如何处理的异常。你不应该得到一个
索引自动失效异常
,如果你得到了,那就是你的代码中的一个bug,你想知道它,这样你就可以修复它了。这意味着不要接受异常


但是,如果我可以在这里引导Clippy,看起来您正在尝试平铺您的MDI子项

在这种情况下,有一种比为
循环编写一堆
,并手动设置孩子的大小和位置更简单的方法。相反,只需在父MDI窗体上调用,并指定其中一个。在这种情况下,您可能需要
mdilaway.TileHorizontal
mdilaway.TileVertical


WinForms将负责精确地自动排列子窗口。

问题行是
try
块中的问题行:

list[counter].SetDesktopLocation(i*list[counter].MdiParent.Width/a, j*list[counter].MdiParent.Height/b);
list[counter].Size = new Size(list[counter].MdiParent.Width/a, list[counter].MdiParent.Height/b);
counter++;
您正在检查
Form.Width
Form.Height
,它们返回屏幕上表单的总大小,包括所有边框。您只能将子窗口放置在父窗体的客户端区域内,因此需要查询。定义为表单的大小,减去边框和标题栏;换句话说,可以放置孩子的形状区域

试着
块重新写入以下内容:

list[counter].SetDesktopLocation(i*list[counter].MdiParent.ClientSize.Width/a, j*list[counter].MdiParent.ClientSize.Height/b);
list[counter].Size = new Size(list[counter].MdiParent.ClientSize.Width/a, list[counter].MdiParent.ClientSize.Height/b);
counter++;
然后扔掉那个愚蠢的空
catch
块。如果抛出异常时所做的一切都是
break
ing,那么捕获异常就没有意义了。它将冒泡到下一个异常处理程序,如果需要,一直到全局异常处理程序。只捕获您专门知道如何处理的异常。你不应该得到一个
索引自动失效异常
,如果你得到了,那就是你的代码中的一个bug,你想知道它,这样你就可以修复它了。这意味着不要接受异常


但是,如果我可以在这里引导Clippy,看起来您正在尝试平铺您的MDI子项

在这种情况下,有一种比为
循环编写一堆
,并手动设置孩子的大小和位置更简单的方法。相反,只需在父MDI窗体上调用,并指定其中一个。在这种情况下,您可能需要
mdilaway.TileHorizontal
mdilaway.TileVertical


WinForms将负责精确地自动排列您的子窗口。

您指定要为5个“没有最后一个窗口”的窗体布局2x3,我认为这意味着您希望在最后一个窗体通常出现的地方有一个空白空间?如果是这种情况,这对您没有帮助,但如果这对您来说并不重要,您可以使用Form.LayoutMDI方法,它是.NET Windows窗体的标准部分:

LayoutMdi(MdiLayout.TileVertical);

不同的是,在上面的场景中,它不会留下空的空间-为了利用空的空间,2个窗口会显得更大。无论如何,请尝试一下,看看是否可以。

您是否指定要为5个表单“无最后一个窗口”布局2x3,我认为这意味着您希望在最后一个表单通常出现的地方有一个空白空间?如果是这种情况,这对您没有帮助,但如果这对您来说并不重要,您可以使用Form.LayoutMDI方法,它是.NET Windows窗体的标准部分:

LayoutMdi(MdiLayout.TileVertical);
不同的是,在上面的场景中,它不会留下空的空间-为了利用空的空间,2个窗口会显得更大。不管怎样,试试看是否对你有好处