Bagaimana cara menggunakan DockStyle.Fill untuk kontrol standar di WPF?

92

Saya terbiasa dari bentuk jendela, yang saya buat panel, tempatkan kontrol di dalamnya dan berikan mereka DockStyle.Filluntuk memaksimalkan ukurannya ke panel sekitarnya.

Di WPF saya ingin memiliki yang sama. Saya memiliki TabControl dan saya ingin ukurannya mengisi formulir sebanyak mungkin. Saya memiliki kontrol pita (RibbonControlsLibrary) dan ingin sisa formulir diisi dengan TabControl pada ukuran maksimal.

(Saya tidak ingin kontrol dock seperti docking di Visual Studio, hanya mekanisme docking lama)

citronas
sumber

Jawaban:

181

WPF setara dengan DockStyle.Fill WinForms adalah:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Ini adalah default untuk hampir semua kontrol, jadi secara umum Anda tidak perlu melakukan apa pun agar kontrol WPF mengisi wadah induknya : Mereka melakukannya secara otomatis. Ini berlaku untuk semua wadah yang tidak menekan anak-anak mereka ke ukuran minimum.

Kesalahan Umum

Sekarang saya akan menjelaskan beberapa kesalahan umum yang mencegah HorizontalAlignment="Stretch" VerticalAlignment="Stretch"bekerja seperti yang diharapkan.

1. Tinggi atau Lebar Eksplisit

Satu kesalahan umum adalah secara eksplisit menentukan Width atau Height untuk sebuah kontrol. Jadi jika Anda memiliki ini:

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

Hapus saja atribut Width dan Height:

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

2. Berisi panel squeezes control ke ukuran minimum

Kesalahan umum lainnya adalah memiliki panel penampung yang menekan kontrol Anda sekencang-kencangnya. Misalnya StackPanel vertikal akan selalu memeras isinya secara vertikal sekecil mungkin:

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

Ubah ke Panel lain dan Anda akan baik-baik saja:

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

Selain itu, setiap baris atau kolom Grid yang tingginya "Otomatis" akan memadatkan isinya ke arah tersebut.

Beberapa contoh wadah yang tidak memadatkan anaknya adalah:

  • ContentControls tidak pernah menekan anak-anak mereka (termasuk Border, Button, CheckBox, ScrollViewer, dan banyak lainnya)
  • Kisi dengan satu baris dan kolom
  • Kisi dengan baris dan kolom berukuran "*"
  • DockPanel tidak memeras anak terakhirnya
  • TabControl tidak memeras isinya

Beberapa contoh wadah yang memang memeras anaknya adalah:

  • StackPanel meremas ke arah Orientasinya
  • Kisi dengan baris atau kolom berukuran "Otomatis" terjepit ke arah itu
  • DockPanel menekan semua kecuali anak terakhirnya ke arah dok mereka
  • TabControl meremas headernya (apa yang ditampilkan di tab)

3. Tinggi atau Lebar Eksplisit lebih jauh

Sungguh menakjubkan berapa kali saya melihat Grid atau DockPanel diberi tinggi dan lebar eksplisit, seperti ini:

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

Secara umum, Anda tidak ingin memberikan Tinggi atau Lebar eksplisit pada Panel apa pun. Langkah pertama saya saat mendiagnosis masalah tata letak adalah menghapus setiap Tinggi atau Lebar eksplisit yang dapat saya temukan.

4. Jendela adalah SizeToContent padahal seharusnya tidak

Saat Anda menggunakan SizeToContent, konten Anda akan diperkecil ke ukuran minimum. Dalam banyak aplikasi, ini sangat berguna dan merupakan pilihan yang tepat. Tetapi jika konten Anda tidak memiliki ukuran "alami" maka Anda mungkin ingin menghilangkan SizeToContent.

Ray Burns
sumber
Saya meninggalkan pertanyaan terkait tata letak baru yang cukup kompleks di sini . Setelah membaca jawaban Anda di sini saya berpikir Anda bisa mengetahuinya. Cheers
Berryl
7
Jawaban luar biasa! Saya berharap saya bisa memberi Anda poin bonus. :)
Jim Raden
@Jim Raden: Anda dapat menambahkan hadiah ke pertanyaan ini dan menetapkan poin ke Ray Burns;)
citronas
1
Catatan tambahan untuk pembaca selanjutnya: itu tidak akan diperbarui dalam tampilan desain sampai Anda mengkompilasi ulang.
David
"<Button Content =" Mengapa saya tidak mengisi jendela? "Width =" 200 "Height =" 20 "/>" membuatku tertawa! XD
Jack Frost
7

Anda bisa melakukan apa yang Anda inginkan hanya dengan mengatakan DockPanel LastChildFill="True"dan kemudian memastikan apa yang Anda inginkan adalah anak terakhir!

Grid adalah binatang dari tata letak yang dapat Anda lakukan hampir semua hal, tetapi DockPanel biasanya merupakan pilihan yang tepat untuk panel tata letak terluar Anda. Berikut adalah contoh psuedocode:

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

    <MyFillingTabControl />
</DockPanel>
Berryl
sumber
5

cukup bungkus kontrol Anda dalam kotak dengan dua baris. Petak akan secara otomatis menggunakan semua ruang yang diberikan padanya dan Anda dapat menentukan baris untuk mengambil semua ruang yang tersisa dengan memberi mereka ketinggian "*". Baris pertama dalam contoh saya (Tinggi = "Otomatis") akan mengambil ruang sebanyak yang dibutuhkan oleh pita. Semoga membantu.

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

  <Ribbon Grid.Row="0" />

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

Dengan menambahkan atribut "Grid.Row = .." ke kontrol anak grid, mereka ditugaskan ke baris grid. Kemudian grid akan mengukur anaknya seperti yang didefinisikan oleh definisi baris.

andyp
sumber
Pergi ke arah yang benar, terima kasih. Saya berhasil memasukkan Grid, tetapi sekarang saya perlu memberi tahu TabControl bahwa ia harus menggunakan semua ukuran yang masih tersedia? Bagaimana saya bisa mencapai itu?
citronas
Anda perlu menambahkan atribut "Grid.Row" untuk TabControl dan memberikan definisi baris yang sesuai dengan tinggi "*" - seperti yang ditunjukkan pada contoh.
andyp
0

Saya mencoba banyak metode di sini tetapi tidak dapat menyelesaikan masalah saya. (Isi kontrol lain di kontrol)

Sampai saya menemukan itu

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

Contoh:

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

Untuk desain yang mudah

<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
sumber