HorizontalAlignment = Stretch, MaxWidth и Left выровнены одновременно?

Кажется, это должно быть легко, но я в тупике. В 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>

Что за хитрость?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
97
0
100 858
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

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

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

Я думаю, вам нужно установить VerticalAlignment = "Top" для текстового поля ... кажется, что по умолчанию растягивается.

Gishu 11.11.2008 12:39

+1. Красиво и чисто. Каждый раз, когда я пытаюсь управлять макетом, привязываясь к некоторой фактической ширине (как в принятом ответе), все становится беспорядочно.

Eren Ersönmez 14.08.2014 09:55

Я только что столкнулся с этим вопросом, пытаясь решить ту же проблему. В моем случае это лучший ответ, поскольку он работает в WinRT. Другой ответ - нет, потому что вы не можете привязать ActualWidth в WinRT.

Slade 25.10.2015 01:24

Slade - я только что сделал это в приложении Windows Store: MaxWidth = "{Binding ActualWidth, ElementName = Layout}", и он отлично работал для привязки MaxWidth к свойству ActualWidth других элементов. Я не уверен, почему это сработало для меня, но он сделал то, что я ожидал, и, как было упомянуто ранее в ответе, в котором было решение для привязки ширины, он не менял размер элемента при изменении размера родительского элемента из-за увеличения окна или меньше.

David Rector 30.04.2016 12:59

Это работает только для последнего столбца. Если у вас есть больше столбцов за столбцом MaxWidth, они также будут перемещены влево.

jor 09.02.2021 16:02
Ответ принят как подходящий

Вы можете установить 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>

Не меняет размер автоматически .. Кажется, подходит для содержания .. Я что-то упускаю?

Gishu 11.11.2008 12:46

Кажется, мой проигрыватель Silverlight вылетает

resopollution 03.06.2009 03:35

@Gishu, убедитесь, что вы установили HorizontalAlignment = "Stretch" на элемент Container . (p.s., я понимаю, что вы задали этот вопрос более 6 лет назад.)

David Murdoch 03.03.2015 02:35

Оба предоставленных ответа сработали для указанной мной проблемы - Спасибо!

Однако в моем реальном приложении я пытался ограничить панель внутри ScrollViewer, и метод Кента не справлялся с этой задачей по какой-то причине, которую я не стал отслеживать. По сути, элементы управления могли выходить за пределы параметра MaxWidth, что противоречило моим намерениям.

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

Вы можете использовать это для ширины вашего DataTemplate:

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

Убедитесь, что ваш корень DataTemplate имеет Margin = "0" (вы можете использовать какую-либо панель в качестве корня и установить Margin для дочерних элементов этого корня)

Я бы использовал 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>

Возможно, я все еще смогу помочь кому-нибудь, кто столкнется с этим вопросом, потому что это очень старая проблема.

Мне это тоже было нужно, и я написал поведение, чтобы позаботиться об этом. Итак, вот поведение:

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 для использования поведения.

Функционально аналогичен принятому ответу, но не требует указания родительского элемента:

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

В моем случае мне пришлось поместить текстовое поле в панель стека, чтобы растянуть текстовое поле с левой стороны. Спасибо за предыдущий пост. В качестве примера я установил цвет фона, чтобы увидеть, что происходит при изменении размера окна.

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

Другие вопросы по теме