StackPanel'in çocuklarına maksimum alanı aşağı doğru doldurmaları nasıl sağlanır?


356

Sadece soldan akan metin ve sağdan yardım kutusu istiyorum.

Yardım kutusu en alta kadar uzanmalıdır.

StackPanelAşağıdaki dış kısmı çıkarırsanız harika çalışır.

Ancak düzen nedeniyle (UserControls dinamik olarak ekliyorum) sarma olması gerekir StackPanel.

Nasıl denedim gördüğünüz gibi GroupBox, altına kadar uzatmak için nasıl alabilirim StackPanel:

  • VerticalAlignment="Stretch"
  • VerticalContentAlignment="Stretch"
  • Height="Auto"

XAML:

<Window x:Class="TestDynamic033.Test3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test3" Height="300" Width="600">
    <StackPanel 
        VerticalAlignment="Stretch" 
        Height="Auto">

        <DockPanel 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            Height="Auto" 
            Margin="10">

            <GroupBox 
                DockPanel.Dock="Right" 
                Header="Help" 
                Width="100" 
                Background="Beige" 
                VerticalAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                Height="Auto">
                <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" />
            </GroupBox>

            <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
                <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
            </StackPanel>

        </DockPanel>
    </StackPanel>
</Window>

Cevap:

Teşekkürler Mark, temizlemek DockPanelyerine kullanarak StackPanel. Genel olarak, kendimi DockPanelWPF düzeni için giderek daha fazla kullandığımı görüyorum , işte sabit XAML:

<Window x:Class="TestDynamic033.Test3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test3" Height="300" Width="600" MinWidth="500" MinHeight="200">
    <DockPanel 
        VerticalAlignment="Stretch" 
        Height="Auto">

        <DockPanel 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            Height="Auto" 
            MinWidth="400"
            Margin="10">

            <GroupBox 
                DockPanel.Dock="Right" 
                Header="Help" 
                Width="100" 
                VerticalAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                Height="Auto">
                <Border CornerRadius="3" Background="Beige">
                    <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" 

                Padding="5"/>
                </Border>
            </GroupBox>

            <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
                <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
            </StackPanel>

        </DockPanel>
    </DockPanel>
</Window>

Biçimlendirme düzeltildi - bir listeden koda gitmekten hoşlanmıyor
Greg

1
GroupBox'ı bu şekilde esnetebilir misiniz? Öyleyse, hangisinin düzeni bozduğunu bulana kadar üst öğelerinizi tek tek eklemeye başlayın.
Drew Noakes

RoBorg: Bilmek güzel, beni şaşırttı, teşekkürler
Edward Tanguay

1
Teşekkürler. Cevabınızı kullanarak çok benzer sorunumu çözmek için 2 iç içe DockPanels kullanabildim!
Yablargo

Yanıtlar:


344

StackPanelSon elemanın kalan tüm alanı kullandığı bir yere istediğiniz gibi geliyor . Ama neden a kullanmıyorsunuz DockPanel? Diğer elemanlar Dekore DockPanelileDockPanel.Dock="Top" ve ardından yardım kontrolü kalan boşluğu doldurabilir.

XAML:

<DockPanel Width="200" Height="200" Background="PowderBlue">
    <TextBlock DockPanel.Dock="Top">Something</TextBlock>
    <TextBlock DockPanel.Dock="Top">Something else</TextBlock>
    <DockPanel
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        Height="Auto" 
        Margin="10">

      <GroupBox 
        DockPanel.Dock="Right" 
        Header="Help" 
        Width="100" 
        Background="Beige" 
        VerticalAlignment="Stretch" 
        VerticalContentAlignment="Stretch" 
        Height="Auto">
        <TextBlock Text="This is the help that is available on the news screen." 
                   TextWrapping="Wrap" />
     </GroupBox>

      <StackPanel DockPanel.Dock="Left" Margin="10" 
           Width="Auto" HorizontalAlignment="Stretch">
          <TextBlock Text="Here is the news that should wrap around." 
                     TextWrapping="Wrap"/>
      </StackPanel>
    </DockPanel>
</DockPanel>

Kullanılmayan bir platformdaysanız DockPanel(örn. WindowsStore), ızgara ile aynı efekti oluşturabilirsiniz. Bunun yerine ızgaralar kullanılarak gerçekleştirilen yukarıdaki örnek:

<Grid Width="200" Height="200" Background="PowderBlue">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0">
        <TextBlock>Something</TextBlock>
        <TextBlock>Something else</TextBlock>
    </StackPanel>
    <Grid Height="Auto" Grid.Row="1" Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <GroupBox
            Width="100"
            Height="Auto"
            Grid.Column="1"
            Background="Beige"
            Header="Help">
            <TextBlock Text="This is the help that is available on the news screen." 
              TextWrapping="Wrap"/>
        </GroupBox>
        <StackPanel Width="Auto" Margin="10" DockPanel.Dock="Left">
            <TextBlock Text="Here is the news that should wrap around." 
              TextWrapping="Wrap"/>
        </StackPanel>
    </Grid>
</Grid>

18
Parlak! StackPanel bunu yapmak için nasıl anlamaya çalışırken son saat geçirdim. Şu andan itibaren, ilk önce burada WPF (ve diğer) bilgilerimi arayacağım.
paxdiablo

7
İstediğimi yapmak için StackPanels'ı almaya çalışırken harcadığım zamana inanamıyorum. Paylaşım için teşekkürler! DockPanels en başından beri istediğim şeydi.
danglund

Görünüşe göre tabletler için dockpanel yok. telerik.com/forums/following-blog-post-and-comparison
JP Hellemons

1
Windows Mağazası uygulamaları için dock paneli yok.
Teoman shipahi

Şimdi hepsi evrensel uygulama ile ilgili ve evrensel uygulamalar henüz DockPanel'i desteklemiyor mu?
yonexbat

105

Bunun olmasının nedeni, yığın panelinin, her bir alt öğeyi, öğeleri yığınladığı eksenin kısıtı olarak pozitif sonsuzlukta ölçmesidir. Alt denetimlerin ne kadar büyük olmak istediklerini döndürmeleri gerekir (pozitif sonsuz, MeasureOverride'dan geçerli bir geri dönüş değildir iki eksende ), böylece her şeyin sığacağı en küçük boyutu döndürürler. Gerçekten ne kadar yer doldurmaları gerektiğini bilmeleri mümkün değil.

Görünümünüzün kaydırma özelliği olması gerekmiyorsa ve yukarıdaki yanıt ihtiyaçlarınızı karşılamıyorsa, kendi panelinizi uygulamanızı öneririm. Muhtemelen doğrudan StackPanel'den türetebilirsiniz ve daha sonra yapmanız gereken tek şey, ArrangeOverride yöntemini değiştirmek ve böylece kalan alanı alt öğeler arasında bölerek (her birine aynı miktarda ekstra alan vererek). Öğeler istediklerinden daha fazla alan verilirse iyi bir şekilde işlenmelidir, ancak onlara daha az verirseniz, hataları görmeye başlayacaksınız.

Her şeyi kaydırmak istiyorsanız, korkarım ki işler biraz daha zor olacak, çünkü ScrollViewer size çalışmak için sonsuz miktarda alan veriyor ve bu da sizi alt öğelerle aynı konuma getirecek aslında. Bu durumda, yeni panelinizde görünüm alanı boyutunu belirlemenizi sağlayan yeni bir özellik oluşturmak isteyebilirsiniz, bunu ScrollViewer'ın boyutuna bağlayabilmeniz gerekir. İdeal olarak , IScrollInfo'yu uygularsınız , ancak hepsini doğru bir şekilde uygulayacaksanız bu karmaşıklaşmaya başlar.


+1, size daha fazlasını veririm, ancak sadece 1'e izin verilir, ilk paragrafınız çok sayıda Microsoft sayfasının başarısız olduğunu, yani sonsuzluğun neden bir yükseklik / genişlik olarak ortaya çıkabileceğini ve kullanılabilir döndürmeye güvenemeyeceğinizi belirtti. .
Aidan

Bir Izgara içindeki StackPanel, oldukça yaygın ihtiyacını kolaylıkla çözer. Alt bit, gerekirse bir ScrollViewer içine konabilir. 2006'dan beri WPF yapıyorum ve özel bir panel yapmak için sadece bir kez ihtiyacım var. Ekstra karmaşıklığı teşvik etmenin iyi bir fikir olduğunu düşünmüyorum.
Chris Bordeman

@ChrisBordeman Izgara içindeki yığın panelinin sorunu nasıl çözdüğünü anladığımdan emin değilim. Buradaki fikir, yığın panelinde kullanılabilir alanı doldurmak için bir veya daha fazla alt öğenin gerilmesidir. Yığın panelini bir ızgaranın içine yerleştirmek bunu yapmaz mı?
Caleb Vear

61

Alternatif bir yöntem, bir sütun ve n satır içeren bir Izgara kullanmaktır . Tüm satır yüksekliklerini Autove en alt satır yüksekliğini olarak ayarlayın 1*.

Izgaraları DockPanels, StackPanels ve WrapPanels'den daha iyi düzen performansına sahip bulduğum için bu yöntemi tercih ederim. Ancak bunları bir ItemTemplate'de (çok sayıda öğe için mizanpajın gerçekleştirildiği yerde) kullanmadığınız sürece, muhtemelen hiçbir zaman fark etmeyeceksiniz.


1
benim için en iyi çözüm. bununla birlikte büyüyen bir satırdan daha fazlasını tanımlamak mümkündür
niyou

18

Değiştirilmiş bir sürümü olan SpicyTaco.AutoGrid'i kullanabilirsiniz StackPanel:

<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="10" Margin="10">
   <Button Content="Info" HorizontalAlignment="Left" st:StackPanel.Fill="Fill"/>
   <Button Content="Cancel"/>
   <Button Content="Save"/>
</st:StackPanel>

İlk düğme doldurulur.

NuGet ile kurabilirsiniz:

Install-Package SpicyTaco.AutoGrid

SpicyTaco.AutoGrid'e göz atmanızı tavsiye ederim . Bu yerine WPF formları için çok yararlıdır DockPanel, StackPanelve Gridve çok kolay ve incelikle germe ile sorunu çözmek. GitHub'daki benioku dosyasına bakmanız yeterli.

<st:AutoGrid Columns="160,*" ChildMargin="3">
    <Label Content="Name:"/>
    <TextBox/>

    <Label Content="E-Mail:"/>
    <TextBox/>

    <Label Content="Comment:"/>
    <TextBox/>
</st:AutoGrid>
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.