codememo

HorizontalAlignment=수평, 최대 너비 및 왼쪽이 동시에 정렬됩니까?

tipmemo 2023. 5. 23. 21:56
반응형

HorizontalAlignment=수평, 최대 너비 및 왼쪽이 동시에 정렬됩니까?

이것은 쉬울 것 같지만 저는 당황스럽습니다.WPF에서는 부모 너비까지 확장되지만 최대 너비까지만 확장되는 TextBox를 원합니다.문제는 저는 그것이 부모님 안에서 정당화되기를 원한다는 것입니다.확장하려면 HorizontalAlignment="Stretch"를 사용해야 하지만 결과가 중앙에 배치됩니다.Horizontal Content Alignment로 실험을 해봤지만 아무 효과가 없는 것 같습니다.

창 크기에 따라 이 파란색 텍스트 상자가 커지고 최대 폭이 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>

두 답변 모두 제가 말한 문제에 효과가 있었습니다. 감사합니다!

하지만 실제 응용 프로그램에서는 ScrollViewer 내부의 패널을 제한하려고 했지만 Kent의 방법은 어떤 이유에서인지 잘 처리되지 않았습니다.기본적으로 컨트롤이 MaxWidth 설정 이상으로 확장되어 제 의도를 꺾을 수 있습니다.

Nir의 기술은 잘 작동했고 Scroll Viewer에 문제가 없었습니다. 단, 주의해야 할 사소한 점이 있습니다.텍스트 상자의 오른쪽 및 왼쪽 여백이 0으로 설정되어 있는지 확인하거나 여백이 방해가 되는지 확인합니다.또한 세로 스크롤 막대가 나타날 때 문제가 발생하지 않도록 실제 너비 대신 ViewportWidth를 사용하도록 바인딩을 변경했습니다.

데이터 템플릿의 너비에 사용할 수 있습니다.

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

DataTemplate 루트에 여백="0"이 있는지 확인합니다(일부 패널을 루트로 사용하고 여백을 해당 루트의 자식으로 설정할 수 있음).

허용된 답변과 기능적으로 유사하지만 상위 요소를 지정할 필요는 없습니다.

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

제 경우에는 텍스트 상자를 왼쪽으로 늘이기 위해 스택 패널에 텍스트 상자를 넣어야 했습니다.이전 게시물 덕분에.예를 들어 창 크기가 변경될 때 발생하는 현상을 확인하기 위해 배경색을 설정했습니다.

<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사용 가능한 공간이 더 있으면 오른쪽으로 정렬합니다.

하지만 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>

언급URL : https://stackoverflow.com/questions/280331/horizontalalignment-stretch-maxwidth-and-left-aligned-at-the-same-time

반응형