HorizontalAlignment = Розтяг, Максимальна ширина та вирівнювання вліво одночасно?


95

Це здається, що це повинно бути легко, але я здивований. У WPF я хотів би TextBox, який тягнеться до ширини батьківського, але лише до максимальної ширини. Проблема полягає в тому, що я хочу, щоб це було виправдано у його батьків. Щоб змусити його розтягнутись, ви повинні використовувати HorizontalAlignment = "Stretch", але тоді результат зосереджується. Я експериментував з HorizontalContentAlignment, але, здається, він нічого не робить.

Як змусити це синє текстове поле зростати з розміром вікна, мати максимальну ширину 200 пікселів і залишатись виправданим?

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

У чому фокус?

Відповіді:


89

Ви можете встановити HorizontalAlignmentліворуч, встановити свій, MaxWidthа потім прив'язати Widthдо ActualWidthбатьківського елемента:

<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
Не має автоматичного розміру. Здається, це відповідає вмісту. Я щось пропускаю?
Gishu

Здається, це розбиває мого гравця Silverlight
resopollution

2
@Gishu, переконайтеся , що ви встановили HorizontalAlignment="Stretch"на Container елементі. (ps, я усвідомлюю, що ви задавали це питання більше 6 років тому.)
Девід Мердок,

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

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

Я думаю, вам потрібно встановити VerticalAlignment = "Вгору" для текстового поля .. Здається, за замовчуванням розтягується.
Gishu

1
+1. Приємно і чисто. Кожен раз, коли я намагаюся керувати компонуванням, прив’язуючи до якоїсь фактичної ширини (як у прийнятій відповіді), речі стають брудними.
Eren Ersönmez

1
Я просто натрапив на це питання, намагаючись вирішити ту саму проблему. У моєму випадку це найкраща відповідь, оскільки це працює в WinRT. Інша відповідь не відповідає тому, що ви не можете прив’язати до ActualWidth в WinRT.
Слейд

Slade - я щойно робив це в додатку Windows Store: MaxWidth = "{Binding ActualWidth, ElementName = Layout}", і він спрацював чудово для прив'язки MaxWidth до інших елементів властивості ActualWidth. Я не впевнений, чому це працювало для мене, але це робило те, що я очікував, і, як було сказано раніше, у відповіді, що було рішення про прив'язку ширини, воно не змінило розмір елемента, коли батьківський розмір змінився через збільшення вікна більшим або менший.
Ректор Девід

8

Обидві наведені відповіді спрацювали над проблемою, яку я заявив - Дякую!

Однак у моєму реальному додатку я намагався обмежити панель всередині ScrollViewer, і метод Кента не справлявся з цим дуже добре з якихось причин, я не потрудився відстежити. В основному елементи керування можуть розширюватися за межі параметра MaxWidth і перемогти мій намір.

Техніка Ніра спрацювала добре і не мала проблем із ScrollViewer, хоча є одна незначна річ, на яку слід стежити. Ви хочете бути впевнені, що правий і лівий поля в TextBox встановлені на 0 або вони будуть перешкоджати. Я також змінив прив'язку, щоб використовувати ViewportWidth замість ActualWidth, щоб уникнути проблем, коли з’явилася вертикальна смуга прокрутки.


6

Ви можете використовувати це для ширини вашого DataTemplate:

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

Переконайтеся, що у вашому корені DataTemplate є маржа = "0" (ви можете використовувати деяку панель як корінь і встановити Поле для дітей цього кореня)


1

Функціонально схожий на прийняту відповідь, але не вимагає вказування батьківського елемента:

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

1

Можливо, я все-таки можу допомогти комусь, хто стикається з цим питанням, адже це дуже стара проблема.

Мені це також було потрібно, і я написав поведінку, щоб подбати про це. Отже ось така поведінка:

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;
            }
        }
    }
}

Тоді ви можете використовувати його так:

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

І нарешті забути використовувати System.Windows.Interactivityпростір імен для використання поведінки.


0

Я б користувався 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

У моєму випадку мені довелося помістити текстове поле на панель стека, щоб розтягнути текстове поле з лівого боку. Завдяки попередньому допису. Тільки для прикладу я встановив колір фону, щоб побачити, що відбувається, коли розмір вікна змінюється.

<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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.