wpf HorizontalAlignment=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
HorizontalAlignment=Stretch, MaxWidth, and Left aligned at the same time?
提问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,它可以延伸到其父项的宽度,但只能达到最大宽度。问题是我希望它在其父级中保持合理。要使其拉伸,您必须使用 HorizontalAlignment="Stretch",但结果是居中的。我已经尝试过 HorizontalContentAlignment,但它似乎没有做任何事情。
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 HorizontalAlignment
to Left, set your MaxWidth
and then bind Width
to the ActualWidth
of the parent element:
您可以设置HorizontalAlignment
为 Left,设置您的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>
回答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.Interactivity
namespace 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>