Panel.Dock Fill игнорируя другие настройки Panel.Dock

154

Если вы создаете панель в форме и устанавливаете для нее Dock = Top, а затем опускаете другую панель и устанавливаете ее Dock = Fill, она может заполнить всю форму, игнорируя первую панель. Изменение порядка вкладок ничего не дает.

Джефф Кускутис
источник

Ответы:

335

Расположение стыковки зависит от порядка элементов управления. Элементы управления закрепляются «кнопкой вверх», поэтому последний элемент управления в коллекции закрепляется первым . Пристыкованный элемент управления учитывает только расположение ранее пристыкованных братьев и сестер. Следовательно, элемент управления с Dock = Fill должен быть первым (верхним) в том же порядке, если вы хотите, чтобы он учитывал другие закрепленные элементы управления. Если это не первый элемент управления, более ранние элементы управления будут перекрывать его.

Это может сбивать с толку, потому что порядок родного брата не обязательно совпадает с визуальным, а порядок родного брата не всегда очевиден с точки зрения дизайна.

Окно «Структура документа» («Просмотр» -> «Другие окна» -> «Структура документа») предоставляет полезное древовидное представление иерархии и порядка элементов управления и позволяет изменить порядок элементов управления в одном элементе.

Вы также можете изменить порядок элементов в непосредственном конструкторе с помощью контекстного меню -> Перевести на передний план / Отправить на задний план, в результате чего элемент управления будет первым или последним из элементов одного уровня. Эти метки меню могут несколько запутать, поскольку фактический эффект зависит от модели макета.

При фиксированных позиционных элементах управления 2D-положение не зависит от порядка одного и того же брата, но когда элементы управления перекрываются, самый ранний элемент в этом порядке будет «сверху», а часть дочерних элементов будет скрываться позже в этом порядке. В этом контексте Bring to front / Отправить назад имеет смысл.

В панелях макета потока или таблицы порядок создания определяет визуальный порядок элементов управления. Там нет перекрывающихся элементов управления. Так что выводить вперед / отправлять назад действительно означает сделать первым или последним в порядке элементов управления.

С пристыкован компоновщик, на передний план / отправить спине может быть еще более запутанной , так как он определяет , в каком порядке стыковка рассчитывается, так что «на передний план » на насыпных стыковка управления переведет управление в середине родителя , принимая во внимание все закрепленные на краю элементы управления.

JacquesB
источник
1
у меня есть панель, полоса состояния и полоса меню, все в форме, и кажется, что когда я закрепляю полосу меню вверху, полосу состояния внизу и заполняю панель, панель не заполняет пространство между две полосы, если это не первый брат (в верхней части окна «Структура документа» над двумя полосами). Перемещение панели вниз (по направлению к «последней») закрывает полосы. Так должен ли элемент управления Dock = Fill быть первым братом в заказе? Я читаю это неправильно? Я использую 3.5 (2008). Это изменилось?
jrsconfitto
53
ТЛ; др; Щелкните правой кнопкой мыши на панели с Dock = Fill и нажмите «Переместить на передний план».
Кристианп
20
+1 для окна структуры документа. Никогда не знал, что это существует, но это так полезно.
Глигоран
2
Как я могу сделать это программно? Я имею в виду, я добавляю элементы управления динамически, поэтому я не могу использовать дизайнер для этого.
Камило Мартин
2
@Camilo: Если вы добавляете элементы управления динамически, вы должны добавлять их в нужном вам порядке.
JacquesB
110

Щелкните правой кнопкой мыши на панели с Dock = Fill и нажмите «Переместить на передний план».

Это делает этот элемент управления созданным последним, который учитывает настройки Dock для других элементов управления в том же контейнере.

Джефф Кускутис
источник
1
Просто, Боже, это действительно меня раздражало
ухмылка
Имеет смысл, когда вы думаете об этом.
Гэри Киндель
7

Другим, потенциально более чистым вариантом является использование элемента управления TableLayout. Установите один ряд желаемой высоты для вашего верхнего дока, а другой ряд, чтобы заполнить 100% для вашего нижнего. Установите обе панели внутри Fill, и все готово.

(TableLayout требует некоторого привыкания, хотя.)

Джон Руди
источник
1
TableLayout также медленнее, чем стыковочные контроллеры для производительности компоновки, особенно если у вас есть вложенные пользовательские элементы управления, которые используют TableLayout. Тем не менее, это дает хороший макет, чтобы быть уверенным.
Ник
1
Поражает ли это производительность то, что обычный пользователь увидел бы в простом случае с двумя панелями, как описано выше? Или это то, что они замечают, когда у вас есть десятки UC, все с макетами, все в одном макете? (По иронии судьбы, приложение, над которым я сейчас работаю, похоже, и производительность кажется нормальной ...)
Джон Руди,
TableLayout довольно легкий. Вы не увидите проблем с производительностью, если просто выложите несколько элементов управления.
Тим
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 была идея с контуром документа, но иерархия не решила мою проблему. Мои элементы управления не были в иерархическом стиле, они были просто перечислены с тем же родителем.

Я узнал, что если вы изменили порядок, он исправит то, как вы хотите, чтобы он выглядел.

Элементы управления в нижней части списка будут перекрывать элементы управления в верхней части окна Document Outline. В вашем случае вы должны убедиться, что первая панель находится ниже второй панели и так далее.

RANONO
источник
0

Вот трюк, который работал для меня ..

Поместите элемент Top и закрепите его сверху.

Поместите Splitter, а также закрепите его сверху, затем отключите (если вы не хотите изменить размер верхней части).

Затем поместите объект Fill и установите Docking на Fill. Объект останется ниже сплиттера.

Джон Кристман
источник
0

Я столкнулся с той же проблемой. Мой был с добавлением новых / пользовательских элементов управления под полосой меню во время выполнения. Проблема заключалась в том, что элементы управления при стыковке решили состыковать сверху и полностью игнорировали полосу меню, что очень раздражает, если вы спросите меня. Поскольку это должно было быть сделано динамически с кодом, а не в режиме разработки, это стало чрезвычайно неприятным. Самый простой способ, который я нашел, - создать панель в режиме дизайна и закрепить ее под полосой меню. Оттуда вы можете просто добавить / удалить элементы управления на панель, и вы можете закрепить его во время выполнения. Нет необходимости связываться со всеми вашими элементами управления в форме, которые на самом деле не нужно менять, слишком много работы в зависимости от того, что вам действительно нужно сделать.

object.dock = Fill
Panel.Controls.Add(object)
Роберт С.
источник
0

Я знаю, что это старый пост, но я обнаружил что-то полезное. Чтобы программно настроить порядок элементов управления для динамически создаваемых элементов управления, вы можете сделать что-то вроде:

parentForm.Controls.SetChildIndex (myPanel, 0) 

В моем случае я сделал это, чтобы панель Dock / Fill стала первым элементом управления в моей форме, чтобы он не перекрывался с другим закрепленным элементом управления, установленным в Dock / Top (полоса меню).

DrLechter
источник