Panel.Dock Fill ignorando outras configurações do Panel.Dock


154

Se você criar um painel em um formulário e configurá-lo para Dock = Top e soltar outro painel e definir Dock = Fill, ele poderá preencher o formulário inteiro, ignorando o primeiro painel. Alterar a ordem das guias não faz nada.

Respostas:


335

O layout de encaixe depende da ordem dos controles dos irmãos. Os controles são encaixados "botão para cima", portanto, o último controle da coleção é encaixado primeiro . Um controle ancorado leva em consideração apenas o layout de irmãos ancorados anteriormente . Portanto, o controle com Dock = Fill deve ser o primeiro (superior) na ordem dos irmãos, se você quiser levar em consideração os outros controles acoplados. Se não for o primeiro controle, os controles anteriores o sobreporão.

Isso pode ser confuso porque a ordem dos irmãos não é necessariamente a mesma da ordem visual, e a ordem dos irmãos nem sempre é aparente na visualização do design.

A janela Estrutura de tópicos do documento (Exibir -> Outras janelas -> Estrutura do documento) fornece uma visualização em árvore útil sobre a hierarquia e a ordem do controle e permite alterar a ordem dos controles irmãos.

Você também pode alterar a ordem dos irmãos diretamente no designer pelo menu de contexto -> Trazer para frente / Enviar para trás, que move o controle para ser o primeiro ou o último dos irmãos. Esses rótulos de menu podem ser um pouco confusos, pois o efeito real depende do modelo de layout.

Com controles posicionados fixos, a posição 2D é independente da ordem dos irmãos, mas quando os controles se sobrepõem, o controle mais cedo na ordem estará "no topo", ocultando parte dos irmãos posteriormente na ordem. Nesse contexto, Trazer para frente / Enviar para trás faz sentido.

Dentro dos painéis de layout de fluxo ou de tabela, a ordem de criação determina a ordem visual dos controles. Não há controles sobrepostos. Portanto, trazer para frente / enviar para trás significa realmente fazer o primeiro ou o último na ordem dos controles.

Com o layout ancorado, o trazer para frente / enviar para trás pode ser ainda mais confuso, pois determina em que ordem o encaixe é calculado; portanto, "trazer para frente" em um controle de encaixe colocará o controle no meio do pai , levando em consideração todos os controles ancorados na borda.


1
Eu tenho um painel, faixa de status e faixa de menu em um formulário e parece que quando encaixo a faixa de menus na parte superior, a faixa de status na parte inferior e encho o painel, o painel não preenche o espaço entre as duas tiras, a menos que seja o primeiro irmão (na parte superior da janela Estrutura de documento acima das duas tiras). Mover o painel para baixo (na direção do "último") cobre as tiras. Portanto, o controle Dock = Fill deve ser o primeiro irmão da ordem? Estou lendo isso errado? estou usando 3.5 (2008). Isso mudou?
Jsconfitto

53
tl; dr; Clique com o botão direito do mouse no painel com Dock = Fill e clique em 'Bring to Front'.
22411

20
+1 para a janela Estrutura de tópicos do documento. Nunca soube que isso existia, mas é tão útil.
gligoran

2
Como posso fazer isso programaticamente? Quero dizer, estou adicionando os controles dinamicamente para não poder usar o designer para fazer isso.
Camilo Martin

2
@ Camilo: Se você adicionar controles dinamicamente, deverá adicioná-los na ordem que desejar.
JacquesB

110

Clique com o botão direito do mouse no painel com Dock = Fill e clique em 'Bring to Front'.

Isso faz com que esse controle seja criado por último, levando em consideração as configurações do Dock em outros controles no mesmo contêiner.


1
Simples, Godsend, este tinha sido realmente me irritar
smirkingman

Faz sentido quando você pensa sobre isso.
precisa

7

Outra opção potencialmente mais limpa é usar o controle TableLayout. Configure uma linha da altura desejada para a doca superior e outra para preencher 100% da parte inferior. Defina os dois painéis dentro de Fill, e pronto.

(TableLayout leva algum tempo para se acostumar, no entanto.)


1
O TableLayout também é mais lento que os controles de acoplamento para o desempenho do layout, principalmente se você tiver controles de usuário aninhados que usam TableLayout. No entanto, produz um bom layout para ter certeza.
Nick

1
Esse desempenho atinge algo que um usuário comum veria em um caso simples de dois painéis, conforme descrito acima? Ou é algo que eles percebem quando você tem dezenas de UCs, todas com layouts, tudo em um layout? (Ironicamente, o aplicativo que eu estou trabalhando atualmente em é assim, e desempenho parece OK ...)
John Rudy

TableLayout é bastante leve. Você não verá problemas de desempenho se estiver apenas definindo alguns controles.
Tim

7

Eu tive o mesmo problema e consegui resolvê-lo.
Se você tiver um contêiner com DockStyle.Fillos outros, também deve ter o DockStyle, mas o Top ou o que você quiser.
O importante é adicionar o controle DockStyle.Fillprimeiro em Controles e depois nos outros.

Exemplo:

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

mas se colocarmos cb primeiro

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

2

Se você não quiser alterar a ordem dos elementos dentro do código, poderá usar o método Container.Controls.SetChildIndex (), com Container sendo, por exemplo, Form, Panel etc., você deseja adicionar seus controles.

Exemplo:

     //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 teve a ideia com o esboço do documento, mas a hierarquia não resolveu meu problema. Meus controles não estavam em um estilo hierárquico; eles foram listados apenas com o mesmo pai.

Aprendi que se você alterasse a ordem, ela corrigirá a aparência que você deseja.

Os controles na parte inferior da lista se sobrepõem aos controles na janela Estrutura de documento. No seu caso, verifique se o primeiro painel está abaixo do segundo e assim por diante.


0

Aqui está um truque que funcionou para mim ..

Coloque o item Top e encaixe-o em cima.

Coloque um divisor e encaixe-o na parte superior, depois defina-o como desativado (a menos que você queira redimensionar a parte superior).

Em seguida, coloque o objeto Fill e defina Docking como Fill. O objeto ficará abaixo do divisor.


0

Eu tive o mesmo problema. A minha era adicionar controles novos / personalizados abaixo da faixa de menus durante o tempo de execução. O problema eram os controles quando encaixados, decidimos encaixar a partir do topo do formulário e ignoramos completamente a faixa do menu, muito irritante se você me perguntar. Como isso tinha que ser feito dinamicamente com código e não durante o modo de design, isso se tornou extremamente frustrante. A maneira mais simples que encontrei é criar um painel durante o modo de design e encaixar abaixo da faixa do menu. A partir daí, basta adicionar / remover os controles ao painel e encaixá-lo durante o tempo de execução. Não é necessário mexer com todos os controles do formulário que realmente não precisam ser alterados; muito trabalho depende do que você realmente precisa fazer.

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

0

Eu sei que este é um post antigo, mas descobri algo útil. Para ajustar programaticamente a ordem de controle de irmãos para os controles criados dinamicamente, você pode fazer algo como:

parentForm.Controls.SetChildIndex (myPanel, 0) 

No meu caso, fiz isso para mover um painel Dock / Fill para ser o primeiro controle no meu formulário, para que não se sobrepusesse a outro controle ancorado definido como Dock / Top (uma faixa de menu).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.