wpf Horizo​​ntalAlignment=Stretch、MaxWidth 和 Left 同时对齐?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/280331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:46:57  来源:igfitidea点击:

HorizontalAlignment=Stretch, MaxWidth, and Left aligned at the same time?

wpfxamlalignmentstretch

提问by Scott Bussinger

This seems like it should be easy but I'm stumped. In WPF, I'd like a TextBox that stretches to the width of it's parent, but only to a maximum width. The problem is that I want it to be left justified within its parent. To get it to stretch you have to use HorizontalAlignment="Stretch", but then the result is centered. I've experimented with HorizontalContentAlignment, but it doesn't seem to do anything.

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

How do I get this blue text box to grow with the size of the window, have a maximum width of 200 pixels, and be left justified?

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

What's the trick?

有什么诀窍?

采纳答案by Nir

You can set HorizontalAlignmentto Left, set your MaxWidthand then bind Widthto the ActualWidthof the parent element:

您可以设置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>

回答by Kent Boogaart

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

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

回答by Scott Bussinger

Both answers given worked for the problem I stated -- Thanks!

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

In my real application though, I was trying to constrain a panel inside of a ScrollViewer and Kent's method didn't handle that very well for some reason I didn't bother to track down. Basically the controls could expand beyond the MaxWidth setting and defeated my intent.

不过,在我的实际应用程序中,我试图将面板限制在 ScrollViewer 中,但由于某种原因,Kent 的方法不能很好地处理该问题,因此我没有费心去追踪。基本上,控件可以扩展到 MaxWidth 设置之外并挫败我的意图。

Nir's technique worked well and didn't have the problem with the ScrollViewer, though there is one minor thing to watch out for. You want to be sure the right and left margins on the TextBox are set to 0 or they'll get in the way. I also changed the binding to use ViewportWidth instead of ActualWidth to avoid issues when the vertical scrollbar appeared.

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

回答by Filip Skakun

You can use this for the Width of your DataTemplate:

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

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

Make sure your DataTemplate root has Margin="0" (you can use some panel as the root and set the Margin to the children of that root)

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

回答by Y C

Maybe I can still help somebody out who bumps into this question, because this is a very old issue.

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

I needed this as well and wrote a behavior to take care of this. So here is the behavior:

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

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

Then you can use it like so:

然后你可以像这样使用它:

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

And finally to forget to use the System.Windows.Interactivitynamespace to use the behavior.

最后忘记使用System.Windows.Interactivity命名空间来使用行为。

回答by maxp

Functionally similar to the accepted answer, but doesn't require the parent element to be specified:

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

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

回答by Patrick Cairns

I would use SharedSizeGroup

我会用 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>