Horizo​​ntalAlignment =拉伸,最大宽度和向左对齐?


95

这似乎应该很容易,但我很困惑。在WPF中,我想要一个TextBox,它可以扩展到其父级的宽度,但只能扩展到最大宽度。问题是我希望它在其父项中保持合理。要使其伸展,您必须使用Horizo​​ntalAlignment =“ Stretch”,但是结果将居中。我已经尝试过Horizo​​ntalContentAlignment,但似乎没有任何作用。

如何使这个蓝色文本框随窗口大小而增长,最大宽度为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>

诀窍是什么?

Answers:


89

您可以设置HorizontalAlignment为Left,设置您的MaxWidth,然后绑定WidthActualWidth父元素的:

<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年前问这个问题的。)
David Murdoch 2015年

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

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

我认为您需要为文本框设置VerticalAlignment =“ Top”。默认情况下似乎是拉伸的。
Gishu

1
+1。干净整洁。每当我尝试通过绑定到某个实际宽度来管理布局(如公认的答案)时,事情都会变得混乱。
ErenErsönmez2014年

1
我只是在尝试解决同一问题时遇到了这个问题。就我而言,这是最好的答案,因为它在WinRT中有效。另一个答案不是,因为您无法在WinRT中绑定ActualWidth。
Slade

Slade-我只是在Windows Store应用程序中执行了此操作:MaxWidth =“ {Binding ActualWidth,ElementName = Layout}”,并且可以很好地将MaxWidth绑定到另一个元素ActualWidth属性。我不确定为什么这对我有用,但它确实达到了我的预期,就像前面在答案中提到的具有Width绑定解决方案的那样,当父级调整大小时,由于使窗口变大或变大,它没有调整元素的大小较小。
David Rector

8

给出的两个答案都可以解决我所说的问题-谢谢!

不过,在我的实际应用程序中,我试图将面板限制在ScrollViewer内,而Kent的方法由于我不愿意追踪的某些原因而不能很好地处理该面板。基本上,控件可以扩展到MaxWidth设置之外,从而破坏了我的意图。

Nir的技术效果很好,并且ScrollViewer没问题,尽管有一点需要注意。您需要确保将TextBox上的左右页边距设置为0,否则它们会受到干扰。我还更改了绑定,以使用ViewportWidth而不是ActualWidth来避免出现垂直滚动条时出现问题。


6

您可以将其用于DataTemplate的宽度:

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

确保您的DataTemplate根目录具有Margin =“ 0”(您可以将某个面板用作根目录,并将Margin设置为该根目录的子级)


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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.