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)

citronas
źródło

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.

Ray Burns
źródło
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>
Berryl
źródło
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.

andyp
źródło
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;
Trương Quốc Khánh
źródło