wpf HorizontalAlignment=是否同时拉伸、最大宽度和左对齐?

rur96b6h  于 2022-12-05  发布在  其他
关注(0)|答案(9)|浏览(210)

这看起来应该很简单,但我被难住了。在WPF中,我想要一个文本框,它可以拉伸到其父文本框的宽度,但只能拉伸到最大宽度。问题是,我希望它在其父文本框中左对齐。要使它拉伸,你必须使用HorizontalAlignment=“Stretch”,但结果是居中的。我已经试验过HorizontalContentAlignment,但它似乎没有任何作用。
如何使此蓝色文本框随窗口的大小增长,最大宽度为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>

有什么诀窍?

68bkxrlz

68bkxrlz1#

您可以将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>
bvjxkvbb

bvjxkvbb2#

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

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

vhipe2zx3#

给出的两个答案都对我所说的问题有效--谢谢!
在我的真实的应用程序中,我试图约束ScrollViewer内部的面板,但肯特的方法处理得不太好,原因我没有去追查。基本上,控件可能会扩展到MaxWidth设置之外,从而破坏了我的意图。
Nir的技术运行得很好,在ScrollViewer中没有出现问题,不过有一点需要注意。您需要确保TextBox的左右边距设置为0,否则它们会妨碍操作。我还将绑定改为使用ViewportWidth而不是ActualWidth,以避免出现垂直滚动条时出现问题。

yks3o0rb

yks3o0rb4#

您可以将此值用于DataTemplate的宽度:

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

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

a7qyws3x

a7qyws3x5#

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

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

wko9yo5t6#

也许我仍然可以帮助那些遇到这个问题的人,因为这是一个非常古老的问题。
我也需要这个,并写了一个行为来处理这个问题。下面是这个行为:

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

7eumitmz

7eumitmz7#

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

dhxwm5r48#

在我的例子中,我不得不把文本框放到一个堆栈面板中,以便拉伸左边的文本框。感谢之前的帖子。只是作为一个例子,我设置了一个背景颜色,看看当窗口大小改变时会发生什么。

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

vktxenjb9#

这些答案对我不起作用,因为我需要一个TextBox来拉伸(即消耗所有可用空间),直到它达到它的MaxWidth,如果有更多的可用空间,则向右对齐。
我创建了这个简单的控件,它沿着YC的答案工作,但不需要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>

相关问题