HorizontalAlignment = Stretch, MaxWidth ve Sol aynı anda mı hizalı?


96

Bu kolay olmalı gibi görünüyor ama şaşkınım. WPF'de, ebeveyninin genişliğine, ancak yalnızca maksimum genişliğe kadar uzanan bir TextBox istiyorum. Sorun şu ki, onun ebeveyni içinde bırakılmasını istiyorum. Esnetmesini sağlamak için HorizontalAlignment = "Stretch" kullanmanız gerekir, ancak daha sonra sonuç ortalanır. HorizontalContentAlignment ile deneyler yaptım, ancak hiçbir şey yapmıyor gibi görünüyor.

Bu mavi metin kutusunun pencerenin boyutuyla büyümesini, maksimum genişliği 200 piksel olmasını ve sola yaslanmış olmasını nasıl sağlayabilirim?

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel>  
    <TextBox Background="Azure" Text="Hello" HorizontalAlignment="Stretch" MaxWidth="200" />
  </StackPanel>
</Page>

Hilesi ne?

Yanıtlar:


89

Sen ayarlayabilirsiniz HorizontalAlignmentkümenizle, Sola MaxWidthbağlamak sonra ve Widthhiç ActualWidthana elemanın:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel Name="Container">   
    <TextBox Background="Azure" 
    Width="{Binding ElementName=Container,Path=ActualWidth}"
    Text="Hello" HorizontalAlignment="Left" MaxWidth="200" />
  </StackPanel>
</Page>

7
Otomatik yeniden boyutlandırmıyor .. İçeriğe uygun görünüyor .. Bir şey mi eksik?
Gishu

Bu, Silverlight oyuncumu
çökertecek

2
@Gishu, emin set yapmak HorizontalAlignment="Stretch"üzerine Container elemanı. (ps, bu soruyu 6 yıldan uzun bir süre önce sorduğunuzun farkındayım.)
David Murdoch

51
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" MaxWidth="200"/>
    </Grid.ColumnDefinitions>

    <TextBox Background="Azure" Text="Hello" />
</Grid>

Metin kutusu için VerticalAlignment = "Top" ayarlamanız gerektiğini düşünüyorum .. varsayılan olarak geniş görünüyor.
Gishu

1
+1. Güzel ve temiz. Düzeni gerçek bir genişliğe bağlayarak (kabul edilen cevapta olduğu gibi) yönetmeye çalıştığımda işler karışıyor.
Eren Ersönmez

1
Aynı sorunu çözmeye çalışırken bu soruyla karşılaştım. Benim durumumda bu, WinRT'de çalıştığı için en iyi cevaptır. Diğer cevap, WinRT'de ActualWidth'e bağlanamadığınız için değil.
Slade

Slade - Bunu bir Windows Mağazası uygulamasında yaptım: MaxWidth = "{Binding ActualWidth, ElementName = Layout}" ve MaxWidth'i başka bir ActualWidth özelliğine bağlamak için iyi çalıştı. Bunun neden benim için işe yaradığından emin değilim ama beklediğim şeyi yaptı ve Genişlik bağlama çözümüne sahip olan yanıtta daha önce bahsedildiği gibi, pencereyi büyütmek veya daha küçük.
David Rector

8

Verilen her iki cevap da belirttiğim sorun için çalıştı - Teşekkürler!

Yine de gerçek uygulamamda, ScrollViewer'ın içindeki bir paneli kısıtlamaya çalışıyordum ve Kent'in yöntemi, bazı nedenlerden dolayı izlemeye zahmet etmedim. Temel olarak kontroller MaxWidth ayarının ötesine geçebilir ve amacımı bozabilir.

Nir'in tekniği iyi çalıştı ve ScrollViewer ile ilgili bir sorun yoktu, ancak dikkat edilmesi gereken küçük bir şey var. TextBox üzerindeki sağ ve sol kenar boşluklarının 0 olarak ayarlandığından emin olmak istersiniz, aksi takdirde bunlar size engel olur. Dikey kaydırma çubuğu göründüğünde sorunları önlemek için Bağlantıyı ActualWidth yerine ViewportWidth'i kullanacak şekilde değiştirdim.


6

Bunu DataTemplate'inizin Genişliği için kullanabilirsiniz:

Width="{Binding ActualWidth,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}"

DataTemplate kökünüzde Margin = "0" olduğundan emin olun (bazı panelleri kök olarak kullanabilir ve Kenar Boşluğunu bu kökün alt öğelerine ayarlayabilirsiniz)


1

Kabul edilen yanıta işlevsel olarak benzer, ancak ana öğenin belirtilmesini gerektirmez:

<TextBox
    Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}"
    MaxWidth="500"
    HorizontalAlignment="Left" />

1

Belki yine de bu soruyla karşılaşan birine yardımcı olabilirim, çünkü bu çok eski bir konu.

Buna da ihtiyacım vardı ve bununla ilgilenmek için bir davranış yazdım. İşte davranış:

public class StretchMaxWidthBehavior : Behavior<FrameworkElement>
{        
    protected override void OnAttached()
    {
        base.OnAttached();
        ((FrameworkElement)this.AssociatedObject.Parent).SizeChanged += this.OnSizeChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        ((FrameworkElement)this.AssociatedObject.Parent).SizeChanged -= this.OnSizeChanged;
    }

    private void OnSizeChanged(object sender, SizeChangedEventArgs e)
    {
        this.SetAlignments();
    }

    private void SetAlignments()
    {
        var slot = LayoutInformation.GetLayoutSlot(this.AssociatedObject);
        var newWidth = slot.Width;
        var newHeight = slot.Height;

        if (!double.IsInfinity(this.AssociatedObject.MaxWidth))
        {
            if (this.AssociatedObject.MaxWidth < newWidth)
            {
                this.AssociatedObject.HorizontalAlignment = HorizontalAlignment.Left;
                this.AssociatedObject.Width = this.AssociatedObject.MaxWidth;
            }
            else
            {
                this.AssociatedObject.HorizontalAlignment = HorizontalAlignment.Stretch;
                this.AssociatedObject.Width = double.NaN;
            }
        }

        if (!double.IsInfinity(this.AssociatedObject.MaxHeight))
        {
            if (this.AssociatedObject.MaxHeight < newHeight)
            {
                this.AssociatedObject.VerticalAlignment = VerticalAlignment.Top;
                this.AssociatedObject.Height = this.AssociatedObject.MaxHeight;
            }
            else
            {
                this.AssociatedObject.VerticalAlignment = VerticalAlignment.Stretch;
                this.AssociatedObject.Height = double.NaN;
            }
        }
    }
}

O zaman bunu şu şekilde kullanabilirsiniz:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <TextBlock Grid.Column="0" Text="Label" />
    <TextBox Grid.Column="1" MaxWidth="600">
          <i:Interaction.Behaviors>                       
               <cbh:StretchMaxWidthBehavior/>
          </i:Interaction.Behaviors>
    </TextBox>
</Grid>

Ve son olarak System.Windows.Interactivity, davranışı kullanmak için ad alanını kullanmayı unutmak .


0

Kullanmak istiyorum SharedSizeGroup

<Grid>
    <Grid.ColumnDefinition>
        <ColumnDefinition SharedSizeGroup="col1"></ColumnDefinition>  
        <ColumnDefinition SharedSizeGroup="col2"></ColumnDefinition>
    </Grid.ColumnDefinition>
    <TextBox Background="Azure" Text="Hello" Grid.Column="1" MaxWidth="200" />
</Grid>

0

Benim durumumda, metin kutusunu sol tarafa uzatmak için metin kutusunu bir yığın paneline yerleştirmek zorunda kaldım. Önceki gönderiye teşekkürler. Sadece bir örnek için, pencere boyutu değiştiğinde ne olacağını görmek için bir arka plan rengi belirledim.

<StackPanel Name="JustContainer" VerticalAlignment="Center" HorizontalAlignment="Stretch" Background="BlueViolet" >
    <TextBox 
       Name="Input" Text="Hello World" 
       MaxWidth="300"
       HorizontalAlignment="Right"
       Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}">
    </TextBox>
</StackPanel>
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.