Horizo​​ntalAlignment = Stretch、MaxWidth、およびLeftは同時に整列されますか?


95

これは簡単なはずですが、困惑しています。WPFでは、親の幅に拡大するが、最大幅まで拡大するTextBoxが必要です。問題は、それが親の中で正当化されることを望んでいることです。ストレッチするには、Horizo​​ntalAlignment = "Stretch"を使用する必要がありますが、結果は中央に配置されます。Horizo​​ntalContentAlignmentを試してみましたが、何もしないようです。

この青いテキストボックスをウィンドウのサイズに合わせて拡大し、最大幅を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>

トリックは何ですか?

回答:


89

HorizontalAlignmentLeftに設定し、を設定してから、親要素のに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>

7
自動サイズ変更しない..コンテンツに適合しているようです..何か不足していますか?
岐阜

これは私の
Silverlight

2
@Gishu、要素に設定HorizontalAlignment="Stretch"してくださいContainer 。(ps、あなたが6年以上前にその質問をしたことは承知しています。)
David Murdoch

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

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

テキストボックスのVerticalAlignment = "Top"を設定する必要があると思います。デフォルトでは、ストレッチされているようです。
岐阜

1
+1。素敵できれい。実際の幅にバインドして(承認された回答のように)レイアウトを管理しようとすると、事態が乱雑になります。
ErenErsönmez2014

1
同じ問題を解決しようとしているときにこの質問に出くわしました。私の場合、WinRTで動作するため、これが最良の答えです。WinRTではActualWidthにバインドできないため、他の答えは違います。
2015年

Slade-私はWindowsストアアプリでこれを実行しました:MaxWidth = "{Binding ActualWidth、ElementName = Layout}"そして、MaxWidthを別の要素ActualWidthプロパティにバインドするためにうまくいきました。なぜこれがうまくいったのかはわかりませんが、期待どおりに機能しました。幅バインディングソリューションの回答で前述したように、ウィンドウを大きくしたり、親をサイズ変更したりすると、要素のサイズが変更されませんでした。小さい。
David Rector 2016

8

与えられた答えは両方とも、私が述べた問題に役立ちました-ありがとう!

実際のアプリケーションでは、ScrollViewer内のパネルを制約しようとしていましたが、Kentのメソッドはそれをうまく処理できませんでした。何らかの理由で追跡する必要がありませんでした。基本的に、コントロールはMaxWidth設定を超えて拡張し、私の意図を無効にする可能性があります。

Nirのテクニックはうまく機能し、ScrollViewerには問題がありませんでしたが、注意すべき点が1つあります。TextBoxの左右の余白が0に設定されていると、邪魔になります。また、垂直スクロールバーが表示されたときの問題を回避するために、ActualWidthではなくViewportWidthを使用するようにバインディングを変更しました。


6

これをDataTemplateの幅に使用できます。

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

DataTemplateルートにMargin = "0"があることを確認します(ルートとしてパネルを使用して、Marginをそのルートの子に設定できます)。


1

機能的には受け入れられた回答に似ていますが、親要素を指定する必要はありません。

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

1

これは非常に古い問題であるため、この質問にぶつかった人をまだ助けることができるかもしれません。

私もこれが必要で、これを処理するための動作を記述しました。だからここに動作があります:

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、動作を使用するために名前空間を使用することを忘れます。


0

私は使うだろう 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>

0

私の場合、テキストボックスを左側に引き伸ばすために、テキストボックスをスタックパネルに配置する必要がありました。以前の投稿に感謝します。ほんの一例として、ウィンドウサイズが変化したときに何が起こるかを確認するために背景色を設定しました。

<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>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.