Come ottenere i controlli in WPF per riempire lo spazio disponibile?


304

Alcuni controlli WPF (come il Button) sembrano consumare felicemente tutto lo spazio disponibile nel suo 'contenitore se non si specifica l'altezza che deve avere.

E alcuni, come quelli che devo usare in questo momento, il (multilinea) TextBoxe il ListBoxpiù sembrano preoccupati solo di prendere lo spazio necessario per adattarsi al loro contenuto, e non di più.

Se metti questi ragazzi in una cella in a UniformGrid, si espanderanno per adattarsi allo spazio disponibile. Tuttavia, le UniformGridistanze non sono adatte a tutte le situazioni. Cosa succede se si dispone di una griglia con alcune righe impostate su * height per dividere l'altezza tra se stessa e altre * righe? Che cosa succede se si dispone di a StackPanele si dispone di a Label, a Liste a Button, come è possibile ottenere l'elenco per occupare tutto lo spazio non occupato dall'etichetta e dal pulsante?

Penso che questo sarebbe davvero un requisito di layout di base, ma non riesco a capire come farli riempire lo spazio che potrebbero (metterli in un DockPanele impostarlo per riempire anche non funziona, sembra, dal momento che l' DockPanelunico occupa lo spazio necessario ai suoi "sottocontrolli".

Una GUI ridimensionabile sarebbe abbastanza orribile se si dovesse giocare con Height, Width, MinHeight, MinWidthetc.

Riesci a legare il tuo Heighte le Widthproprietà alla cella della griglia che occupi? O c'è un altro modo per farlo?


1
UniformGrid è incredibile, il mio nuovo tag goto predefinito. Mi è piaciuta la semplicità di Stackpanels (mi ricorda un div) ma Uniform Grid fa esattamente quello di cui ho bisogno.
Terrance

Re UniformGrid. L'enfasi è su Uniform. Sembra che non sia possibile regolare la larghezza della colonna senza altezze di riga. È adatto solo se ogni contenuto ha le stesse dimensioni. Ho sostituito il mio StackPanel con una griglia e Stretch ha funzionato come mi aspettavo.
pdschuller,

Questo articolo mi ha aiutato ad allungare le caselle di testo.
jpaugh,

Risposte:


162

Ogni controllo derivante da Panelimplementa una logica di layout distinta eseguita in Measure()e Arrange():

  • Measure() determina la dimensione del pannello e ciascuno dei suoi figli
  • Arrange() determina il rettangolo in cui viene eseguito il rendering di ciascun controllo

L'ultimo figlio del DockPanelriempie lo spazio rimanente. È possibile disattivare questo comportamento impostando la LastChildproprietà false.

Il StackPanelchiede ogni bambino per la sua dimensione desiderata e poi li pile. Il pannello di stack chiama Measure()ogni bambino, con una dimensione disponibile di Infinitye quindi utilizza la dimensione desiderata del bambino.

A Gridoccupa tutto lo spazio disponibile, tuttavia, imposterà ogni bambino nella dimensione desiderata e poi li centrerà nella cella.

È possibile implementare la propria logica di layout derivando Panele quindi sovrascrivendo MeasureOverride()e ArrangeOverride().

Vedi questo articolo per un semplice esempio.


8
Il link ora è morto
user3690202

6
@ user3690202 Archive.org è tuo amico. Link rianimato.
ruffin,

4
L'argomento esiste ancora in MSDN, ma il collegamento è cambiato in questo documento: docs.microsoft.com/en-us/dotnet/framework/wpf/controls/…
Andrea Antonangeli,

2
The last child of the DockPanel fills the remaining space: questa era la chiave mancante per la mia comprensione. Ho sempre pensato che l'elemento senza Dock esplicito riempisse lo spazio.
Scoperto il

238

Ci sono anche alcune proprietà che puoi impostare per forzare un controllo a riempire il suo spazio disponibile quando altrimenti non lo farebbe. Ad esempio, puoi dire:

HorizontalContentAlignment="Stretch"

... per forzare il contenuto di un controllo ad allungarsi orizzontalmente. Oppure puoi dire:

HorizontalAlignment="Stretch"

... per forzare il controllo stesso ad allungarsi orizzontalmente per riempire il suo genitore.


88
Il pannello più famoso menzionato in tutti questi casi è StackPanel. Non contiene proprietà ContentAlignment e l'impostazione dei figli su Stretch non avrà alcun effetto all'interno di una griglia a stella. Molto frustrante. È quasi come se StackPanel fosse il primo contenitore scritto dal team WPF e soffre per questo.
Brent Schooley,

4
@Brent - ahh! Sono stato bloccato nel tentativo di riempire correttamente i contenuti del mio stackpanel. Grazie! Pensavo fosse solo qualcosa che stavo facendo molto male.
Ashley Grenon,

8
Il pannello Stack di @townsean è molto limitato, puoi ottenere un comportamento simile con lo stretching usando UniformGrid e impostando Rows o Columns su 0
ForbesLindesay

2
@ Tuskan360 UniformGrid consente solo alle celle di avere le stesse dimensioni. Alla fine ho usato una griglia, sembra funzionare. Fastidioso come StackPanel non faccia ciò per cui è stato progettato.
TarkaDaal,

4
@TarkaDaal yeh, UniformGrid se tutto ha le stesse dimensioni, Grid se si desidera specificare dimensioni relative complesse, impilare il pannello a dimensioni adeguate in base al contenuto e ignorare lo spazio disponibile.
ForbesLindesay,

18

Bene, l'ho capito da solo, subito dopo la pubblicazione, che è il modo più imbarazzante. :)

Sembra che ogni membro di StackPanel riempirà semplicemente la sua dimensione minima richiesta.

Nel DockPanel, avevo ancorato le cose nell'ordine sbagliato. Se TextBox o ListBox è l'unico elemento ancorato senza allineamento o se sono gli ultimi aggiunti, riempiranno lo spazio rimanente come desiderato.

Mi piacerebbe vedere un metodo più elegante per gestirlo, ma lo farà.


Voglio solo sottolineare (su questa vecchia domanda!) Che "senza un allineamento" è una frase chiave qui, almeno era per me.
MikeBaz - MSFT,

4

Utilizzare le proprietà del layout HorizontalAlignment e VerticalAlignment . Controllano come un elemento utilizza lo spazio che ha all'interno del suo genitore quando è disponibile più spazio di quello richiesto dall'elemento.

La larghezza di uno StackPanel, ad esempio, sarà larga quanto l'elemento più largo che contiene. Quindi, tutti gli elementi più stretti hanno un po 'di spazio in eccesso. Le proprietà di allineamento controllano ciò che fa l'elemento figlio con lo spazio aggiuntivo.

Il valore predefinito per entrambe le proprietà è Allunga, quindi l'elemento figlio viene allungato per riempire tutto lo spazio disponibile. Le opzioni aggiuntive includono Sinistra, Centro e Destra per Allineamento orizzontale e Alto, Centro e In basso per Allineamento verticale .


31
Se questo fosse sempre vero, la domanda originale non sarebbe stata posta. Prendi, ad esempio, uno StackPanel orizzontale con un'etichetta e una casella di testo. C'è spazio extra a destra del TextBox. TextBox è impostato su Larghezza automatica. L'impostazione di Stretch per HorizontalAlignment non farà in modo che TextBox riempia lo spazio rimanente.
Brent Schooley,

Nulla è sempre vero, ma questa risposta funziona per le mie esigenze: DockPanel, Immagine.
Alehro
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.