HorizontalAlignment = Kéo dài, Chiều rộng tối đa và Căn trái cùng một lúc?


95

Điều này có vẻ dễ dàng nhưng tôi rất bối rối. Trong WPF, tôi muốn một TextBox kéo dài đến chiều rộng của nó, nhưng chỉ với chiều rộng tối đa. Vấn đề là tôi muốn nó được công bằng bên trong cha mẹ của nó. Để làm cho nó kéo dài, bạn phải sử dụng HorizontalAlignment = "Stretch", nhưng sau đó kết quả được căn giữa. Tôi đã thử nghiệm với HorizontalContentAlignment, nhưng nó có vẻ không hiệu quả.

Làm cách nào để hộp văn bản màu xanh lam này phát triển với kích thước của cửa sổ, có chiều rộng tối đa là 200 pixel và được căn trái?

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

Thủ thuật là gì?

Câu trả lời:


89

Bạn có thể đặt HorizontalAlignmentthành Left, đặt của bạn MaxWidthvà sau đó liên kết Widthvới ActualWidthphần tử mẹ:

<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
Không tự động kích thước .. Có vẻ phù hợp với nội dung .. tôi có thiếu cái gì đó không?
Gishu

Điều này dường như sụp đổ chơi Silverlight của tôi
resopollution

2
@Gishu, hãy chắc chắn rằng bạn thiết lập HorizontalAlignment="Stretch"trên Container phần tử. (ps, tôi nhận ra rằng bạn đã hỏi câu hỏi đó hơn 6 năm trước.)
David Murdoch

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

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

Tôi nghĩ bạn cần đặt VerticalAlignment = "Top" cho hộp văn bản .. dường như được kéo dài theo mặc định.
Gishu

1
+1. Đẹp và sạch sẽ. Bất cứ khi nào tôi cố gắng quản lý bố cục bằng cách liên kết với một số chiều rộng thực tế (như trong câu trả lời được chấp nhận), mọi thứ trở nên lộn xộn.
Eren Ersönmez

1
Tôi vừa gặp câu hỏi này trong khi cố gắng giải quyết vấn đề tương tự. Trong trường hợp của tôi, đây là câu trả lời tốt nhất vì nó hoạt động trong WinRT. Câu trả lời khác là không vì bạn không thể ràng buộc ActualWidth trong WinRT.
Slade

Slade - Tôi vừa làm điều này trong một ứng dụng Windows Store: MaxWidth = "{Binding ActualWidth, ElementName = Layout}" và nó hoạt động tốt khi liên kết MaxWidth với các phần tử khác thuộc tính ActualWidth. Tôi không chắc tại sao điều này lại hiệu quả với tôi nhưng nó đã làm những gì tôi mong đợi và giống như đã được đề cập trước đó trong câu trả lời có giải pháp ràng buộc Chiều rộng, nó không thay đổi kích thước phần tử khi cha thay đổi kích thước do làm cho cửa sổ lớn hơn hoặc nhỏ hơn.
David Hiệu trưởng

8

Cả hai câu trả lời được đưa ra đều phù hợp với vấn đề tôi đã nêu - Cảm ơn!

Tuy nhiên, trong ứng dụng thực của tôi, tôi đang cố gắng giới hạn một bảng điều khiển bên trong ScrollViewer và phương pháp của Kent không xử lý tốt điều đó vì một số lý do tôi không buồn theo dõi. Về cơ bản, các điều khiển có thể mở rộng ra ngoài cài đặt MaxWidth và đánh bại ý định của tôi.

Kỹ thuật của Nir hoạt động tốt và không gặp vấn đề với ScrollViewer, mặc dù có một điều nhỏ cần chú ý. Bạn muốn đảm bảo lề phải và trái trên TextBox được đặt thành 0 nếu không chúng sẽ cản trở. Tôi cũng đã thay đổi liên kết để sử dụng ViewportWidth thay vì ActualWidth để tránh các sự cố khi thanh cuộn dọc xuất hiện.


6

Bạn có thể sử dụng cái này cho Chiều rộng của DataTemplate:

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

Đảm bảo thư mục gốc DataTemplate của bạn có Margin = "0" (bạn có thể sử dụng một số bảng điều khiển làm thư mục gốc và đặt Margin thành phần con của thư mục gốc đó)


1

Về mặt chức năng, tương tự như câu trả lời được chấp nhận, nhưng không yêu cầu chỉ định phần tử gốc:

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

1

Có lẽ tôi vẫn có thể giúp ai đó gặp phải câu hỏi này, bởi vì đây là một vấn đề rất cũ.

Tôi cũng cần điều này và đã viết một hành vi để giải quyết vấn đề này. Vì vậy, đây là hành vi:

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

Sau đó, bạn có thể sử dụng nó như vậy:

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

Và cuối cùng để quên sử dụng System.Windows.Interactivitykhông gian tên để sử dụng hành vi.


0

tôi sẽ dùng 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

Trong trường hợp của tôi, tôi phải đặt hộp văn bản vào một bảng điều khiển ngăn xếp để kéo hộp văn bản ở bên trái. Cảm ơn bài viết trước. Chỉ để làm ví dụ, tôi đã đặt màu nền để xem điều gì sẽ xảy ra khi kích thước cửa sổ thay đổi.

<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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.