Come utilizzare DockStyle.Fill per i controlli standard in WPF?


92

Sono abituato a windows form, che creo un pannello, posto i controlli al suo interno e li do DockStyle.Fillper massimizzare la loro dimensione al pannello circostante.

In WPF voglio avere lo stesso. Ho un TabControl e voglio che le sue dimensioni riempiano il più possibile il modulo. Ho un controllo della barra multifunzione (RibbonControlsLibrary) e desidero che il resto del modulo venga riempito con TabControl alla dimensione massima.

(Non voglio ancorare i controlli come l'ancoraggio in Visual Studio, solo i vecchi meccanismi di ancoraggio)

Risposte:


183

L'equivalente WPF di DockStyle.Fill di WinForms è:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Questa è l'impostazione predefinita per quasi i controlli, quindi in generale non devi fare nulla per fare in modo che un controllo WPF riempia il suo contenitore padre : lo fanno automaticamente. Questo è vero per tutti i contenitori che non comprimono i loro figli alla dimensione minima.

Errori comuni

Spiegherò ora diversi errori comuni che impediscono HorizontalAlignment="Stretch" VerticalAlignment="Stretch"di funzionare come previsto.

1. Altezza o larghezza esplicite

Un errore comune consiste nello specificare in modo esplicito una larghezza o un'altezza per un controllo. Quindi, se hai questo:

<Grid>
  <Button Content="Why am I not filling the window?" Width="200" Height="20" />
  ...
</Grid>

Basta rimuovere gli attributi Larghezza e Altezza:

<Grid>
  <Button Content="Ahhh... problem solved" />
  ...
</Grid>

2. Il pannello di contenimento comprime il controllo alla dimensione minima

Un altro errore comune è quello di avere il pannello di contenimento che stringe il controllo il più possibile. Ad esempio, uno StackPanel verticale comprimerà sempre i suoi contenuti verticalmente il più piccolo possibile:

<StackPanel>
  <Button Content="Why am I squished flat?" />
</StackPanel>

Passa a un altro pannello e sarai pronto per iniziare:

<DockPanel>
  <Button Content="I am no longer squished." />
</DockPanel>

Inoltre, qualsiasi riga o colonna Grid la cui altezza è "Auto" comprimerà in modo simile il suo contenuto in quella direzione.

Alcuni esempi di contenitori che non schiacciano i loro figli sono:

  • ContentControls non stringono mai i propri figli (questo include Border, Button, CheckBox, ScrollViewer e molti altri)
  • Griglia con una singola riga e colonna
  • Griglia con righe e colonne di dimensioni "*"
  • DockPanel non stringe il suo ultimo figlio
  • TabControl non ne comprime il contenuto

Alcuni esempi di contenitori che schiacciano i loro figli sono:

  • StackPanel si comprime nella sua direzione di orientamento
  • La griglia con una riga o una colonna di dimensioni "Auto" si restringe in quella direzione
  • DockPanel spinge tutti, tranne l'ultimo figlio, nella loro direzione di attracco
  • TabControl stringe la sua intestazione (ciò che viene visualizzato nella scheda)

3. Altezza o larghezza esplicite più fuori

È incredibile quante volte vedo Grid o DockPanel con un'altezza e una larghezza esplicite, in questo modo:

<Grid Width="200" Height="100">
  <Button Content="I am unnecessarily constrainted by my containing panel" />
</Grid>

In generale non si vuole mai dare a nessun pannello un'altezza o una larghezza esplicite. Il mio primo passo durante la diagnosi dei problemi di layout è rimuovere ogni altezza o larghezza esplicita che riesco a trovare.

4. Window è SizeToContent quando non dovrebbe esserlo

Quando si utilizza SizeToContent, il contenuto verrà ridotto alla dimensione minima. In molte applicazioni questo è molto utile ed è la scelta corretta. Ma se il tuo contenuto non ha dimensioni "naturali", probabilmente vorrai omettere SizeToContent.


Ho lasciato una nuova domanda relativa al layout abbastanza complessa qui . Dopo aver letto la tua risposta qui sto pensando che tu possa capirlo. Saluti
Berryl

7
Ottima risposta! Vorrei poterti in qualche modo darti punti bonus. :)
Jim Raden

@ Jim Raden: puoi aggiungere una taglia a questa domanda e assegnare i punti a Ray Burns;)
citronas

1
Nota a margine per i futuri lettori: non si aggiornerà nella visualizzazione struttura finché non verrà ricompilato.
David,

"<Button Content =" Perché non sto riempiendo la finestra? "Width =" 200 "Height =" 20 "/>" mi ha fatto ridere! XD
Jack Frost

7

Puoi fare quello che vuoi semplicemente dicendo DockPanel LastChildFill="True"e poi assicurandoti che quello che vuoi essere il riempitivo sia effettivamente l'ultimo bambino!

La griglia è la bestia di un layout che puoi far fare quasi tutto, ma il DockPanel è solitamente la scelta giusta per il tuo pannello di layout più esterno. Ecco un esempio di psuedocode:

<DockPanel LastChildFill="True">
    <MyMenuBar DockPanel.Dock="Top"/>
    <MyStatus DockPanel.Dock="Bottom"/>

    <MyFillingTabControl />
</DockPanel>

5

avvolgi i tuoi controlli in una griglia con due righe. La griglia utilizzerà automaticamente tutto lo spazio assegnato e puoi definire le righe in modo da occupare tutto lo spazio rimasto assegnando loro un'altezza di "*". La prima riga nel mio esempio (Altezza = "Auto") occuperà tutto lo spazio necessario per il nastro. Spero che aiuti.

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Ribbon Grid.Row="0" />

  <TabPage Grid.Row="1" />
</Grid>

Aggiungendo l'attributo "Grid.Row = .." ai controlli figlio della griglia, vengono assegnati alle righe della griglia. Quindi la griglia ridimensionerà i suoi figli come definito dalle definizioni di riga.


Va nella giusta direzione, grazie. Sono riuscito a inserire il Grid, ma ora devo dire al TabControl che dovrebbe utilizzare tutte le dimensioni che sono ancora disponibili? Come posso ottenerlo?
citronas

È necessario aggiungere l'attributo "Grid.Row" per TabControl e dare alla definizione di riga corrispondente un'altezza di "*", proprio come mostrato nell'esempio.
andyp

0

Ho provato molti metodi qui ma non riesco a risolvere il mio problema. (Riempi altro controllo in controllo)

Fino a quando ho trovato lo

<Name_Control Height="auto" Width="auto"/>
//default
//HorizontalAlignment="Stretch" 
//VerticalAlignment="Stretch"

Esempio:

//UserControl:
<UserControl Name="UC_Test" Height="auto" Width="auto" />
//Grid: 
<Grid Name="Grid_test" Grid.ColumnSpan="2" Grid.Row="2" />
//Code: 
Grid_test.Children.Add(UC_Test);

Per un design semplice

<UserControl Name="UC_Test" Height="100" Width="100" />
//Code
Grid_test.Children.Add(UC_Test);
UC_Test.Width = Double.NaN;
UC_Test.Height = Double.NaN;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.