Panel.Dock填充,忽略其他Panel.Dock设置


Answers:


335

对接布局取决于同级控件的顺序。控件停靠在“按钮上”,因此集合中的最后一个控件首先停靠。停靠控件仅考虑了先前停靠的兄弟姐妹的布局。因此,如果您希望Dock = Fill的控件考虑到其他停靠的控件,则该控件应在同级控件中位于第一个(顶部)。如果不是第一个控件,则较早的控件将与它重叠。

这可能会造成混淆,因为同级顺序不一定与视觉顺序相同,并且同级顺序从设计视图中并不总是显而易见的。

文档大纲窗口(视图- >其他窗口- >文件轮廓)给出了一个有用的树视图控件上的层次结构和秩序,并允许您更改控件的同级次序。

您还可以直接在设计器中通过上下文菜单-> Bring to front / Send back back来更改兄弟姐妹的顺序,这会将控件移动到兄弟姐妹中的第一个或最后一个。这些菜单标签可能会有些混乱,因为实际效果取决于布局模型。

对于固定位置的控件,2D位置与兄弟姐妹顺序无关,但是当控件重叠时,最早的控件将在“顶部”,从而在该顺序的后面隐藏部分兄弟姐妹。在这种情况下,向前/向后发送是有意义的。

在流或表布局面板内部,创建顺序确定控件的视觉顺序。没有重叠的控件。因此,向前/向后发送实际上意味着按照控件的顺序进行操作。

使用停靠的布局时,“前移/后退”可能会更加令人困惑,因为它确定了对接的计算顺序,因此,在对接控件上“前移”会将控件放置在父级的中间,并考虑所有边缘对接控件。


1
我在窗体上都有一个面板,状态栏和菜单栏,似乎当我将菜单栏停靠在顶部,状态栏停靠在底部并填充面板时,该面板没有填充两个面板之间的空间。除非它是第一个兄弟姐妹,否则是两个条带(位于两个条带上方的“文档大纲”窗口的顶部)。向下移动面板(朝“最后”方向)覆盖条带。那么,Dock = Fill控件是否应该实际上是该顺序中的第一个兄弟?我读错了吗?我正在使用3.5(2008)。这个改变了吗?
jrsconfitto

53
tl; dr; 用Dock = Fill右键单击面板,然后单击'Bring to Front'。
kristianp 2011年

20
+1为“文档大纲”窗口。从来不知道这存在,但它是如此有用。
gligoran 2012年

2
如何以编程方式执行此操作?我的意思是,我正在动态添加控件,因此无法使用设计器执行此操作。
卡米洛·马丁

2
@Camilo:如果动态添加控件,则应按所需顺序添加它们。
JacquesB


7

另一个可能更清洁的选项是使用TableLayout控件。为您的顶部坞站设置一行所需高度,并为您的底部设置另一行以填充100%的高度。将两个面板都设置为Fill,即可完成。

(不过,TableLayout确实需要一些习惯。)


1
TableLayout也比对接控制布​​局性能慢,尤其是当您嵌套了使用TableLayout的用户控件时。但是,可以肯定的是,它的布局确实不错。
尼克

1
如上所述,在两个面板的简单情况下,这种性能是否达到了普通用户会看到的水平?还是当您有数十个UC,所有UC都在一个布局中时,他们会注意到吗?(具有讽刺意味的是,我目前正在使用的应用程序就是这样,并且性能似乎还不错……)
John Rudy

TableLayout非常轻巧。如果仅布置一些控件,就不会看到性能问题。
蒂姆(Tim)

7

我遇到了同样的问题,并且设法解决了。
如果您与DockStyle.Fill其他人有一个容器,则还应该有DockStyle,但Top或任何您想要的容器 。
重要的是DockStyle.Fill首先在“控件”中添加控件,然后在其他控件中添加 。

例:

ComboBox cb = new ComboBox();
cb.Dock =  DockStyle.Top;

GridView gv = new GridView();
gv.Dock =  DockStyle.Fill;

Controls.Add(gv); // this is okay
Controls.Add(cb);

但是如果我们把cb首先

Controls.Add(cb);
Controls.Add(gv); // gv will overlap the combo box.

2

如果您不想更改代码中元素的顺序,则可以使用Container.Controls.SetChildIndex()方法,其中Container是要添加控件的例如Form,Panel等。

例:

     //Container ------------------------------------
     Panel Container = new Panel();

     //Top-Docked Element ---------------------------
     ButtonArea = new FlowLayoutPanel();
     Container.Controls.Add(ButtonArea);
     Container.Controls.SetChildIndex(ButtonArea, 1);
     ButtonArea.Dock = DockStyle.Top;

     //Fill-Docked Element --------------------------
     box = new RichTextBox();
     Container.Controls.Add(box);
     Container.Controls.SetChildIndex(box, 0); //setting this to 0 does the trick
     box.Dock = DockStyle.Fill;

1

JacquesB想到了文档大纲,但是层次结构并不能解决我的问题。我的控件不是分层式的,它们只是与同一父级一起列出。

我了解到,如果您更改了订单,它将可以固定您想要的外观。

列表底部的控件将与“文档大纲”窗口中顶部的控件重叠。在您的情况下,请确保第一个面板在第二个面板下方,依此类推。


0

这是一个对我有用的技巧。

放置最上面的项目并将其停靠在最上面。

放置一个拆分器,并将其停靠在顶部,然后将其设置为禁用(除非您要调整顶部的大小)。

然后放置“填充”对象,并将“停放”设置为“填充”。该对象将保持在拆分器下方。


0

我遇到了同样的问题。我的是在运行时在菜单栏下方添加新的/自定义控件。问题是停靠时的控件,决定从窗体的顶部停靠,并完全忽略了菜单栏,如果您问我,这会很烦人。由于必须使用代码动态完成此操作,而不是在设计模式下完成,因此这变得非常令人沮丧。我发现的最简单的方法是在设计模式下创建一个面板,并将其停靠在菜单栏下方。从那里您可以在面板中添加/删除控件,并且可以在运行时将其停靠。无需弄乱表单上所有不需要真正更改的控件,根据实际需要做很多工作。

object.dock = Fill
Panel.Controls.Add(object)

0

我知道这是一篇旧文章,但是我发现了一些有用的东西。要以编程方式为动态创建的控件调整同级控件的顺序,您可以执行以下操作:

parentForm.Controls.SetChildIndex (myPanel, 0) 

就我而言,我这样做是为了将Dock / Fill面板移动为窗体中的第一个控件,以使其不会与设置为Dock / Top(菜单栏)的另一个停靠控件重叠。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.