English 中文(简体)
水平对齐=拉伸,最大宽度和左对齐同时进行?
原标题:
  • 时间:2008-11-11 08:26:34
  •  标签:

这似乎应该很容易,但我迷糊了。在WPF中,我想要一个文本框,它可以伸展到其父级的宽度,但仅限于最大宽度。问题在于,我希望它在其父级内左对齐。要使其伸展,您必须使用HorizontalAlignment =“Stretch”,但结果是居中的。我已经尝试过HorizontalAlignment,但似乎没有任何作用。

我该如何使这个蓝色文本框随着窗口大小增加而增加,在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>

提供的两个答案都解决了我提出的问题--谢谢!

然而在我的实际应用中,我正在尝试将一个面板限制在一个滚动查看器内,但是肯特的方法对此处理得不太好,原因我没有追踪过。基本上,控件可以超出最大宽度设置,并打败了我的意图。

Nir的技术很好,也没有出现与ScrollViewer相关的问题,但是需要注意一件小事情。你需要确保TextBox的右和左边距设置为0,否则会妨碍。我还改动了绑定,使用ViewportWidth而非ActualWidth,避免垂直滚动条出现时出现问题。

你可以将此用于你的DataTemplate的宽度:

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

请确保您的DataTemplate根元素具有Margin =“0”(您可以使用某些面板作为根元素,并将Margin设置为该根元素的子元素)。

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

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

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

我也需要这个,所以我写了一段行为来处理这个问题。以下是这个行为:

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>

In my case I had to put textbox into a stack panel in order to stretch textbox on left side. Thanks to previous post. Just for an example I did set a background color to see what’s happens when window size is changing.

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

这些答案对我没用,因为我需要一个 TextBox 来拉伸(即占用所有可用空间),直到达到它的 MaxWidth ,如果有更多的空间可用,则对齐到右侧。

我创建了这个简单的控件,它的工作原理类似于Y C的答案,但不需要System.Windows.Interactivity

public class StretchAlignmentPanel : ContentControl
{
    public StretchAlignmentPanel()
    {
        this.SizeChanged += StretchAlignmentPanel_SizeChanged;
    }

    public static readonly DependencyProperty HorizontalFallbackAlignmentProperty = DependencyProperty.Register(
        nameof(HorizontalFallbackAlignment), typeof(HorizontalAlignment), typeof(StretchAlignmentPanel), new PropertyMetadata(HorizontalAlignment.Stretch));

    public HorizontalAlignment HorizontalFallbackAlignment
    {
        get { return (HorizontalAlignment)GetValue(HorizontalFallbackAlignmentProperty); }
        set { SetValue(HorizontalFallbackAlignmentProperty, value); }
    }

    public static readonly DependencyProperty VerticalFallbackAlignmentProperty = DependencyProperty.Register(
        nameof(VerticalFallbackAlignment), typeof(VerticalAlignment), typeof(StretchAlignmentPanel), new PropertyMetadata(VerticalAlignment.Stretch));

    public VerticalAlignment VerticalFallbackAlignment
    {
        get { return (VerticalAlignment)GetValue(VerticalFallbackAlignmentProperty); }
        set { SetValue(VerticalFallbackAlignmentProperty, value); }
    }

    private void StretchAlignmentPanel_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
    {
        var fe = this.Content as FrameworkElement;
        if (fe == null) return;
        
        if(e.WidthChanged) applyHorizontalAlignment(fe);
        if(e.HeightChanged) applyVerticalAlignment(fe);
    }

    private void applyHorizontalAlignment(FrameworkElement fe)
    {
        if (HorizontalFallbackAlignment == HorizontalAlignment.Stretch) return;

        if (this.ActualWidth > fe.MaxWidth)
        {
            fe.HorizontalAlignment = HorizontalFallbackAlignment;
            fe.Width = fe.MaxWidth;
        }
        else
        {
            fe.HorizontalAlignment = HorizontalAlignment.Stretch;
            fe.Width = double.NaN;
        }
    }

    private void applyVerticalAlignment(FrameworkElement fe)
    {
        if (VerticalFallbackAlignment == VerticalAlignment.Stretch) return;

        if (this.ActualHeight > fe.MaxHeight)
        {
            fe.VerticalAlignment = VerticalFallbackAlignment;
            fe.Height= fe.MaxHeight;
        }
        else
        {
            fe.VerticalAlignment = VerticalAlignment.Stretch;
            fe.Height= double.NaN;
        }
    }
}

它可以这样使用:

<controls:StretchAlignmentPanel HorizontalFallbackAlignment="Right">
    <TextBox MaxWidth="200" MinWidth="100" Text="Example"/>
</controls:StretchAlignmentPanel>




相关问题
热门标签