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>
Что за хитрость?
Решение
Вы можете установить 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>
Другие советы
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MaxWidth="200"/>
</Grid.ColumnDefinitions>
<TextBox Background="Azure" Text="Hello" />
</Grid>
Оба ответа помогли решить поставленную мною проблему - спасибо!
В моем реальном приложении я пытался ограничить панель внутри ScrollViewer, а метод Кента не очень хорошо справлялся с этим, по какой-то причине я не удосужился его отследить. По сути, элементы управления могут выходить за рамки параметра MaxWidth и победить мои намерения.
Техника Нира работала хорошо и не имела проблем с ScrollViewer, хотя есть одна небольшая вещь, на которую следует обратить внимание. Вы хотите быть уверены, что правое и левое поля в TextBox установлены в 0, иначе они будут мешать. Я также изменил привязку, чтобы использовать ViewportWidth вместо ActualWidth, чтобы избежать проблем при появлении вертикальной полосы прокрутки.
Вы можете использовать это для ширины вашего шаблона данных:
Width="{Binding ActualWidth,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}"
Убедитесь, что корень вашего DataTemplate имеет Margin = " 0 " (вы можете использовать некоторую панель в качестве корня и установить Margin для дочерних элементов этого корня)
Может быть, я все еще могу помочь кому-то, кто сталкивается с этим вопросом, потому что это очень старая проблема.
Я тоже нуждался в этом и написал поведение, чтобы позаботиться об этом. Итак, вот поведение:
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
для использования поведения.
Я бы использовал 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>