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.

Jeff Cuscutis
fonte

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.

JacquesB
fonte
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.

Jeff Cuscutis
fonte
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.)

John Rudy
fonte
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.
Pandichie Anton-Valentin
fonte
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;
Marcus
fonte
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.

RANONO
fonte
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.

John Christman
fonte
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)
Robert S.
fonte
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).

DrLechter
fonte