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

问题描述 投票:139回答:9

如果在窗体上创建面板并将其设置为Dock = Top并放下另一个面板并设置其Dock = Fill,则可能会填充整个窗体,而忽略第一个面板。更改Tab键顺序不起作用。

c# .net winforms visual-studio-2005
9个回答
307
投票

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

这可能令人困惑,因为兄弟顺序不一定与视觉顺序相同,并且兄弟顺序在设计视图中并不总是显而易见的。

“文档大纲”窗口(“视图” - >“其他Windows” - >“文档大纲”)为控件层次结构和顺序提供了有用的树视图,并允许您更改控件的同级顺序。

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

对于固定定位控件,2D位置与兄弟顺序无关,但是当控件重叠时,顺序中最早的控件将“在顶部”,稍后将按顺序隐藏兄弟姐妹的一部分。在这种情况下,带到前面/发送到后面是有道理的。

在内部流程或表格布局面板中,创建顺序决定了控件的可视顺序。没有重叠的控件。所以带到前面/后面发送真的意味着按照控件的顺序制作第一个或最后一个。

使用停靠布局时,前置/后置发送可能会更加混乱,因为它确定了对接的计算顺序,因此填充对接控件上的“前置”会将控件置于父对象的中间位置,考虑所有边缘停靠控件。


100
投票

用Dock = Fill右键单击面板,然后单击“Bring to Front”。

这使得此控件最后创建,它考虑了同一容器中其他控件的Dock设置。


7
投票

另一个可能更清晰的选择是使用TableLayout控件。为顶部底座设置所需高度的一行,为底部填充另一行100%。将两个面板都设置为Fill,然后就完成了。

(TableLayout确实需要一些时间来习惯。)


6
投票

我遇到了同样的问题,我设法解决了这个问题。 如果你有一个带DockStyle.Fill的容器,其他人也应该有DockStyle但是Top或者你想要的任何东西。 重要的是首先在Controls中添加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.

1
投票

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

我了解到,如果你改变了顺序,它将以你想要的方式修复它。

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


1
投票

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

例:

     //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;

0
投票

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

放置顶部项目并将其停靠在顶部。

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

然后放置填充对象并将Docking设置为Fill。物体将保持在分离器下方。


0
投票

我遇到了同样的问题。我的目的是在运行时在菜单条下面添加新的/自定义控件。问题是停靠时的控件,决定从表单的顶部停靠并完全忽略菜单条,如果你问我非常讨厌。由于必须使用代码动态完成,而不是在设计模式下,这变得非常令人沮丧。我找到的最简单的方法是在设计模式下创建一个面板并停靠在菜单条下面。从那里你可以添加/删除控件到面板,你可以在运行时停靠它。您不需要在表单上混淆所有不需要更改的控件,根据您真正需要做的事情进行太多工作。

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

0
投票

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

parentForm.Controls.SetChildIndex (myPanel, 0) 

在我的情况下,我这样做是为了将Dock / Fill面板移动到我的表单中的第一个控件,以便它不会与另一个停靠的控件设置为Dock / Top(菜单条)重叠。

© www.soinside.com 2019 - 2024. All rights reserved.