WPF'de standart denetimler için DockStyle.Fill nasıl kullanılır?


92

Bir panel oluşturduğum, kontrolleri içine yerleştirdiğim ve DockStyle.Fillçevreleyen panele boyutlarını maksimize etmelerini sağladığım pencere formlarından alınıyorum.

WPF'de de aynısına sahip olmak istiyorum. TabControl'üm var ve boyutunun olabildiğince fazla formu doldurmasını istiyorum. Bir şerit denetimim var (RibbonControlsLibrary) ve formun geri kalanının TabControl ile maksimum boyutta doldurulmasını istiyorum.

(Visual Studio'da yerleştirme gibi denetimleri yerleştirmek istemiyorum, yalnızca eski yerleştirme mekanizmaları)

Yanıtlar:


181

WinForms 'DockStyle.Fill'in WPF eşdeğeri şöyledir:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

Bu, neredeyse kontroller için varsayılandır, bu nedenle genel olarak bir WPF kontrolünün üst konteynerini doldurması için hiçbir şey yapmanız gerekmez : Bunu otomatik olarak yaparlar. Bu, çocuklarını minimum boyuta sıkıştırmayan tüm kaplar için geçerlidir.

Yaygın hatalar

Şimdi HorizontalAlignment="Stretch" VerticalAlignment="Stretch"beklendiği gibi çalışmayı engelleyen birkaç yaygın hatayı açıklayacağım .

1. Açık Yükseklik veya Genişlik

Yaygın bir hata, bir kontrol için açıkça bir Genişlik veya Yükseklik belirtmektir. Yani eğer buna sahipseniz:

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

Genişlik ve Yükseklik niteliklerini kaldırmanız yeterlidir:

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

2. Panel sıkma kontrolünü minimum boyutta içerir

Diğer bir yaygın hata, kapsama panelinin kontrolünüzü gidebildiği kadar sıkı sıkıştırmasıdır. Örneğin dikey bir StackPanel, içeriğini her zaman dikey olarak gidebilecekleri kadar küçük sıkıştıracaktır:

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

Başka bir Panele geçin ve gitmekte fayda var:

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

Ayrıca, yüksekliği "Otomatik" olan herhangi bir Izgara satırı veya sütunu, içeriğini benzer şekilde bu yönde sıkıştıracaktır.

Çocuklarını sıkıştırmayan bazı kap örnekleri şunlardır:

  • ContentControls altlarını asla sıkıştırmaz (buna Border, Button, CheckBox, ScrollViewer ve diğerleri dahildir)
  • Tek sıralı ve sütunlu ızgara
  • "*" Boyutlu satır ve sütunlara sahip ızgara
  • DockPanel son çocuğunu sıkıştırmaz
  • TabControl içeriğini sıkıştırmaz

Çocuklarını sıkıştıran bazı kap örnekleri şunlardır:

  • StackPanel, Oryantasyon yönünde sıkıştırıyor
  • "Otomatik" boyutlu satır veya sütun içeren ızgara, bu yönde sıkıştırır
  • DockPanel, son alt öğesi hariç her şeyi yuva yönünde sıkıştırır
  • TabControl başlığını sıkıştırır (sekmede görüntülenen)

3. Açık Yükseklik veya Genişlik daha dışarıda

Açık bir yükseklik ve genişlik verildiğinde Grid veya DockPanel'i kaç kez görüyorum, bunun gibi:

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

Genel olarak hiçbir Panele kesin bir Yükseklik veya Genişlik vermek istemezsiniz. Yerleşim sorunlarını teşhis ederken ilk adımım, bulabildiğim her açık Yükseklik veya Genişliği kaldırmaktır.

4. Pencere, olmaması gerektiğinde SizeToContent'tir

SizeToContent'i kullandığınızda, içeriğiniz minimum boyuta sıkıştırılacaktır. Birçok uygulamada bu çok kullanışlıdır ve doğru seçimdir. Ancak içeriğinizin "doğal" boyutu yoksa, büyük olasılıkla SizeToContent'i çıkarmak isteyeceksiniz.


Burada oldukça karmaşık yeni bir düzen ile ilgili soru bıraktım . Cevabınızı burada okuduktan sonra çözebileceğinizi düşünüyorum. Cheers
Berryl

7
Mükemmel cevap! Keşke sana bir şekilde bonus puan verebilseydim. :)
Jim Raden

@Jim Raden: Bu soruya bir ödül ekleyebilir ve puanları Ray Burns'e atayabilirsiniz;)
citronas

1
Gelecekteki okuyucular için ek not: Siz yeniden derleyene kadar tasarım görünümünde güncellenmeyecektir.
David

"<Düğme İçeriği =" Pencereyi neden doldurmuyorum? "Genişlik =" 200 "Yükseklik =" 20 "/>" beni kırdı! XD
Jack Frost

7

İstediğini sadece söyleyerek DockPanel LastChildFill="True"ve sonra dolgu yapmak istediğin şeyin aslında son çocuk olduğundan emin olarak yapabilirsin!

Izgara, her şeyi yapabileceğiniz bir düzen canavarıdır, ancak DockPanel genellikle en dıştaki düzen paneliniz için doğru seçimdir. İşte bir psuedocode örneği:

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

    <MyFillingTabControl />
</DockPanel>

5

kontrollerinizi iki satırlı bir ızgaraya kaydırmanız yeterlidir. Izgara, kendisine verilen tüm boşluğu otomatik olarak kullanır ve satırlara "*" yüksekliği vererek kalan tüm alanı kaplayacak şekilde tanımlayabilirsiniz. Örneğimdeki ilk satır (Yükseklik = "Otomatik"), şerit için gerektiği kadar yer kaplayacaktır. Umarım yardımcı olur.

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

  <Ribbon Grid.Row="0" />

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

Izgaranın alt denetimlerine "Grid.Row = .." özniteliğini ekleyerek, ızgaranın satırlarına atanırlar. Daha sonra ızgara, satır tanımlarında tanımlandığı gibi alt öğelerini boyutlandıracaktır.


Doğru yöne gider, teşekkürler. Grid'i yerleştirmeyi başardım, ancak şimdi TabControl'e hala mevcut olan tüm boyutu kullanması gerektiğini söylemem gerekiyor. Bunu nasıl başarabilirim?
citronas

TabControl için "Grid.Row" özniteliğini eklemeniz ve ilgili satır tanımına, örnekte gösterildiği gibi bir yükseklik "*" vermeniz gerekir.
andyp

0

Burada birçok yöntem denedim ama sorunumu çözemedim. (Diğer denetimi denetimde doldur)

Ben bulana kadar

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

Misal:

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

Kolay tasarım için

<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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.