102

这似乎应该很容易,但我很难过。在 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>

有什么诀窍?

4

8 回答 8

93

您可以设置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>
于 2008-11-11T09:25:52.043 回答
53
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" MaxWidth="200"/>
    </Grid.ColumnDefinitions>

    <TextBox Background="Azure" Text="Hello" />
</Grid>
于 2008-11-11T09:13:42.867 回答
8

给出的两个答案都适用于我所说的问题 - 谢谢!

不过,在我的实际应用程序中,我试图将一个面板限制在 ScrollViewer 内,而 Kent 的方法由于某种原因并没有很好地处理这个问题,我没有费心去追查。基本上,这些控件可以扩展到 MaxWidth 设置之外并破坏了我的意图。

Nir 的技术运行良好,并且 ScrollViewer 没有问题,但需要注意一件小事。您要确保将 TextBox 上的左右边距设置为 0,否则它们会妨碍您。我还将绑定更改为使用 ViewportWidth 而不是 ActualWidth 以避免出现垂直滚动条时出现问题。

于 2008-11-11T11:26:27.887 回答
7

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

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

确保您的 DataTemplate 根有 Margin="0" (您可以使用某些面板作为根并将 Margin 设置为该根的子级)

于 2010-08-26T08:25:00.590 回答
3

也许我仍然可以帮助遇到这个问题的人,因为这是一个非常古老的问题。

我也需要这个,并写了一个行为来解决这个问题。所以这是行为:

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命名空间来使用行为。

于 2018-06-19T12:44:53.103 回答
2

功能类似于接受的答案,但不需要指定父元素:

<TextBox
    Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}"
    MaxWidth="500"
    HorizontalAlignment="Left" />
于 2019-10-31T10:34:50.117 回答
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>
于 2017-09-03T19:47:19.347 回答
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>
于 2020-06-15T15:56:42.110 回答