【问题标题】:HorizontalAlignment=Stretch, MaxWidth, and Left aligned at the same time?Horizo​​ntalAlignment=Stretch、MaxWidth 和 Left 同时对齐?
【发布时间】:2010-09-21 18:34:56
【问题描述】:

这似乎应该很容易,但我很难过。在 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>

有什么诀窍?

【问题讨论】:

    标签: wpf xaml alignment stretch


    【解决方案1】:
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" MaxWidth="200"/>
        </Grid.ColumnDefinitions>
    
        <TextBox Background="Azure" Text="Hello" />
    </Grid>
    

    【讨论】:

    • 我认为你需要为文本框设置 VerticalAlignment="Top" .. 默认情况下似乎是拉伸的。
    • +1。干净整洁。每当我尝试通过绑定到一些实际宽度来管理布局时(如在接受的答案中),事情就会变得一团糟。
    • 我在尝试解决同样的问题时遇到了这个问题。就我而言,这是最好的答案,因为它适用于 WinRT。另一个答案不是因为您无法在 WinRT 中绑定 ActualWidth。
    • Slade - 我刚刚在 Windows 应用商店应用程序中执行此操作: MaxWidth="{Binding ActualWidth, ElementName=Layout}" 并且它可以很好地将 MaxWidth 绑定到另一个元素 ActualWidth 属性。我不确定为什么这对我有用,但它达到了我的预期,就像前面提到的具有宽度绑定解决方案的答案一样,当父级调整大小时它没有调整元素的大小,因为窗口更大或更小。
    • 这仅适用于最后一列。我在MaxWidth 的列后面还有更多列,它们也会被拉到左边。
    【解决方案2】:

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

    【讨论】:

    • 不自​​动调整大小..似乎适合内容..我错过了什么吗?
    • 这似乎让我的 silverlight 播放器崩溃了
    • @Gishu,确保在Container 元素上设置HorizontalAlignment="Stretch"。 (附言,我知道你在 6 年前就问过这个问题。)
    【解决方案3】:

    给出的两个答案都适用于我所说的问题——谢谢!

    不过,在我的实际应用程序中,我试图将一个面板限制在 ScrollViewer 内,而 Kent 的方法由于某种原因没有很好地处理这个问题,我没有费心去追查。基本上,这些控件可以扩展到 MaxWidth 设置之外并破坏了我的意图。

    Nir 的技术运行良好,并且 ScrollViewer 没有问题,但需要注意一件小事。您要确保将 TextBox 上的左右边距设置为 0,否则它们会妨碍您。我还将绑定更改为使用 ViewportWidth 而不是 ActualWidth 以避免出现垂直滚动条时出现问题。

    【讨论】:

      【解决方案4】:

      您可以将其用于 DataTemplate 的宽度:

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          我也需要这个,并写了一个行为来解决这个问题。所以这是行为:

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

          【讨论】:

            【解决方案7】:

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

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

            【讨论】:

              【解决方案8】:

              就我而言,我必须将文本框放入堆栈面板中才能在左侧拉伸文本框。 感谢之前的帖子。 举个例子,我确实设置了背景颜色,以查看当窗口大小发生变化时会发生什么。

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

              【讨论】:

                猜你喜欢
                • 2012-08-17
                • 2012-10-13
                • 2016-10-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-05-09
                • 2011-05-21
                • 2018-01-19
                相关资源
                最近更新 更多