Jak używać DockStyle.Fill do standardowych formantów w WPF?


92

Jestem używany z formularzy okien, że tworzę panel, umieszczam w nim kontrolki i nadaję im DockStyle.Fillmaksymalny rozmiar do otaczającego panelu.

W WPF chcę mieć to samo. Mam TabControl i chcę, aby jego rozmiar wypełniał jak najwięcej formularza. Mam formant wstążki (RibbonControlsLibrary) i chcę, aby reszta formularza została wypełniona TabControl w maksymalnym rozmiarze.

(Nie chcę zadokować formantów, takich jak dokowanie w programie Visual Studio, tylko stare mechanizmy dokowania)

Odpowiedzi:


181

Odpowiednik WPF DockStyle.Fill WinForms to:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Jest to ustawienie domyślne dla prawie kontrolek, więc generalnie nie musisz nic robić, aby formant WPF wypełnił swój kontener nadrzędny : robią to automatycznie. Dotyczy to wszystkich pojemników, które nie ściskają swoich dzieci do minimalnego rozmiaru.

Typowe błędy

Wyjaśnię teraz kilka typowych błędów, które uniemożliwiają HorizontalAlignment="Stretch" VerticalAlignment="Stretch"działanie zgodnie z oczekiwaniami.

1. Wyraźna wysokość lub szerokość

Jednym z typowych błędów jest jawne określenie szerokości lub wysokości kontrolki. Więc jeśli masz to:

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

Po prostu usuń atrybuty Szerokość i Wysokość:

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

2. Zawierający panel ściska kontrolę do minimalnego rozmiaru

Innym częstym błędem jest ściskanie panelu sterującego tak mocno, jak to tylko możliwe. Na przykład pionowy panel StackPanel zawsze będzie ściskał zawartość w pionie tak mała, jak tylko się da:

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

Zmień panel na inny i gotowe:

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

Ponadto każdy wiersz lub kolumna siatki, której wysokość jest ustawiona na „Auto”, podobnie ściśnie swoją zawartość w tym kierunku.

Oto kilka przykładów pojemników, które nie ściskają swoich dzieci:

  • ContentControls nigdy nie ściskają swoich elementów podrzędnych (w tym Border, Button, CheckBox, ScrollViewer i wiele innych)
  • Siatka z jednym wierszem i jedną kolumną
  • Siatka z wierszami i kolumnami o rozmiarze „*”
  • DockPanel nie ściska swojego ostatniego elementu podrzędnego
  • TabControl nie ściska swojej zawartości

Oto kilka przykładów pojemników, które wyciskają swoje dzieci:

  • StackPanel ściska się w kierunku orientacji
  • Siatka z wierszem lub kolumną o rozmiarze „Auto” jest ściskana w tym kierunku
  • DockPanel ściska wszystko oprócz ostatniego elementu podrzędnego w kierunku doku
  • TabControl ściska swój nagłówek (co jest wyświetlane na karcie)

3. Wyraźna wysokość lub szerokość dalej

To niesamowite, ile razy widzę Grid lub DockPanel z określoną wysokością i szerokością, na przykład:

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

Ogólnie rzecz biorąc, nigdy nie chcesz nadawać żadnemu panelowi wyraźnej wysokości ani szerokości. Moim pierwszym krokiem podczas diagnozowania problemów z układem jest usunięcie każdej wyraźnej wysokości lub szerokości, jaką mogę znaleźć.

4. Okno to SizeToContent, kiedy nie powinno

Podczas korzystania z SizeToContent zawartość zostanie ściśnięta do minimalnego rozmiaru. W wielu zastosowaniach jest to bardzo przydatne i jest właściwym wyborem. Ale jeśli zawartość nie ma „naturalnego” rozmiaru, prawdopodobnie będziesz chciał pominąć SizeToContent.


Zostawiłem tutaj dość złożone pytanie związane z nowym układem . Po przeczytaniu odpowiedzi tutaj myślę, że możesz to rozgryźć. Pozdrawiam
— Berryl

7
Doskonała odpowiedź! Chciałbym móc w jakiś sposób dać ci dodatkowe punkty. :)
— Jim Raden,

@Jim Raden: Możesz dodać nagrodę do tego pytania i przypisać punkty Rayowi Burnsowi;)
— citronas

1
Uwaga dodatkowa dla przyszłych czytelników: nie zaktualizuje się w widoku projektu do czasu ponownej kompilacji.
— David

"<Button Content =" Dlaczego nie wypełniam okna? "Width =" 200 "Height =" 20 "/>" rozwalił mnie! XD
— Jack Frost,

7

Możesz robić, co chcesz, po prostu mówiąc, DockPanel LastChildFill="True"a następnie upewniając się, że to, co chcesz być wypełniaczem, jest w rzeczywistości ostatnim dzieckiem!

Siatka to bestia układu, który możesz zrobić prawie wszystko, ale DockPanel jest zwykle właściwym wyborem dla najbardziej zewnętrznego panelu układu. Oto przykład psuedokodu:

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

    <MyFillingTabControl />
</DockPanel>

5

po prostu zawiń kontrolki w siatkę z dwoma wierszami. Siatka automatycznie wykorzysta całe przydzielone jej miejsce i możesz zdefiniować wiersze, które zajmą całą pozostałą przestrzeń, nadając im wysokość „*”. Pierwszy wiersz w moim przykładzie (wysokość = „Auto”) zajmie tyle miejsca, ile potrzeba na wstążce. Mam nadzieję, że to pomoże.

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

  <Ribbon Grid.Row="0" />

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

Dodając atrybut „Grid.Row = ..” do kontrolek podrzędnych siatki, są one przypisywane do wierszy siatki. Wtedy siatka zmieni rozmiar swoich dzieci zgodnie z definicją wierszy.


Idzie we właściwym kierunku, dzięki. Udało mi się wstawić Grid, ale teraz muszę powiedzieć TabControl, że powinien używać całego rozmiaru, który jest nadal dostępny? Jak mogę to osiągnąć?
— citronas

Musisz dodać atrybut „Grid.Row” dla TabControl i nadać odpowiedniej definicji wiersza wysokość „*” - tak jak pokazano w przykładzie.
— andyp

0

Próbowałem tutaj wielu metod, ale nie mogę rozwiązać mojego problemu. (Wypełnij inną kontrolę w kontroli)

Dopóki go nie znalazłem

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

Przykład:

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

Dla łatwego projektowania

<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;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.