2011-08-01 87 views
10

我有很多情况下,我有面板或网格自动调整大小,但如果他们包含TextBoxTextWrapping="Wrap"TextBox继续扩大面板/网格的权利真正需要很久之前,如图像如下:如何优先考虑WPF文本框自动大小?

Textbox expanding the panel

我所希望做的是有TextBox通过环绕文字填写其面积它试图向右展开之前。这个问题的一个简单的例子是:

<Grid> 
    <Grid Background="Black" /> 
    <Grid VerticalAlignment="Top" HorizontalAlignment="Left" Background="White"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto"></ColumnDefinition> 
     </Grid.ColumnDefinitions> 
     <TextBox TextWrapping="Wrap" Height="120" MinWidth="200" /> 
    </Grid> 
</Grid> 

我发现SO here过类似的问题,但最好的解决方案张贴并没有让TextBox扩大。该解决方案是这样的:比修改行为延伸TextBox其他

<Grid> 
    <Grid Background="Black"> 
    </Grid> 
    <Grid VerticalAlignment="Top" HorizontalAlignment="Left" Background="White"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto"></ColumnDefinition> 
     </Grid.ColumnDefinitions> 
     <Border BorderThickness="0" x:Name="border" Margin="0.5" /> 
     <TextBox TextWrapping="Wrap" Height="120" MinWidth="200" Width="{Binding ActualWidth, ElementName=border}" /> 
    </Grid> 
</Grid> 

任何想法?谢谢!

+0

确保我明白了这个问题:你是否在说如果文本框可以支持10行文本,你希望它只在第11行输入时才开始水平扩展? – sellmeadog

+0

@crazyarabian,正确的,我只想在输入第n行(超出可见范围)时水平展开。就像某种方式,如果我可以触发文本框想要垂直滚动时,然后允许展开。 –

+0

为什么你想让文本框水平展开?从可用性的角度来看,这没有多大意义,似乎令人困惑,因为预期的行为可能是a)垂直扩展或b)垂直滚动 – sellmeadog

回答

3

虽然我不建议这样做,因为我觉得它引入了意外的行为给用户,这似乎达到你的要求:

XAML:

<TextBox ... MinHeight="120" Width="200" SizeChanged="TextBox_SizeChanged" />

代码背后:

private void TextBox_SizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    try 
    { 
     if (e.PreviousSize == Size.Parse("0,0")) return; 
     if (e.PreviousSize == e.NewSize) return; 

     if (e.HeightChanged) 
     { 
      ((TextBox)sender).Width = e.PreviousSize.Width + 20; 
     } 
    } 

    finally 
    { 
     e.Handled = true; 
    } 
} 

几件事情需要注意:1)为了这个工作,你必须既MinHeightWidth以允许扩展和2)20的水平扩展只是用于测试目的的任意值;你会想出一个更可靠的计算可变扩展值的方法。

+0

+1这个想法,谢谢!我会接受,如果它导致最终的解决方案。如果您添加MaxHeight,此解决方案可以正常工作,并且在达到最大宽度时垂直滚动会开始。主要的问题是设置一个固定的宽度,所以TextBox最初不会伸展到网格,如果用户调整窗口大小,它也不会调整。 –

+0

没有使用这个解决方案,而是接受了这个解决方案,因为我提出了你的可用性建议,导致了解决方案。 –

0

我现在的解决方案是上面提到的边界技巧,并且更好地解释here。为使TextBox自动填充Grid中的区域,并在用户增大或缩小窗口时调整其大小,占位边框的边距必须为,比TextBox的边距大

该解决方案不会像最初所期望的那样水平自动扩展,但它比单行文本扩展到正确的问题要好。在图像面板的

例XAML上面边境招(文本框的保证金是5):

<Grid> 
    <!-- Diagram Window --> 
    <Expander Header="{Binding Source={StaticResource labels}, Path=DiagramToolBoxHeader}" IsExpanded="True"> 
     <Grid MinWidth="200" MinHeight="200"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"></RowDefinition> 
       <RowDefinition Height="Auto" ></RowDefinition> 
       <RowDefinition Height="Auto"></RowDefinition> 
       <RowDefinition Height="Auto"></RowDefinition> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="10"></ColumnDefinition> 
       <ColumnDefinition Width="Auto"></ColumnDefinition> 
       <ColumnDefinition Width="*"></ColumnDefinition> 
       <ColumnDefinition Width="10"></ColumnDefinition> 
      </Grid.ColumnDefinitions> 
      <Label Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Style="{StaticResource LabelHeader}" Content="{Binding Title}" /> 
      <Label Grid.Row="1" Grid.Column="1" Style="{StaticResource SolutionDiagramNameInput}" Content="{Binding SolutionDiagramNameLabel}" /> 
      <Label Grid.Row="2" Grid.Column="1" Style="{StaticResource DescriptionInput}" Content="{Binding DescriptionLabel}" /> 
      <TextBox Grid.Row="1" Grid.Column="2" Text="{Binding SolutionDiagramName, Mode=TwoWay}" /> 
      <Border Name="PlaceHolderBorder" Grid.Column="2" Margin="7"/> 
      <TextBox Grid.Row="2" Grid.Column="2" Text="{Binding Description, Mode=TwoWay}" VerticalScrollBarVisibility="Auto" 
        TextAlignment="Left" TextWrapping="Wrap" Width="{Binding ElementName=PlaceHolderBorder, Path=ActualWidth}" /> 
      <StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="2" Margin="5"> 
       <Button Command="{Binding UpdateCommand}" Content="{Binding UpdateButtonLabel}"></Button> 
       <Button Command="{Binding ResetCommand}" Content="{Binding ResetButtonLabel}"></Button> 
       <Button Command="{Binding DefaultsCommand}" Content="{Binding DefaultsButtonLabel}"></Button> 
       <Button Command="{Binding CloseConfirmCommand}" Content="{Binding CloseButtonLabel}"></Button> 
      </StackPanel> 
     </Grid> 
    </Expander> 
</Grid> 
4

有一个简单的手段来得到它的工作。使用帆布,然后绑定文本框到ActualWidth的画布的宽度高度画布到文本框的的ActualHeight。使用它

enter image description here

和调整

我们的生产应用程序的

<Canvas 
    x:Name="Canvas" 
    Height="{Binding ElementName=TextBlock, Path=ActualHeight}" 
    VerticalAlignment="Stretch" HorizontalAlignment="Stretch"> 

     <TextBlock 
      x:Name="TextBlock" 
      Width="{Binding ElementName=Canvas, Path=ActualWidth}" 
      TextWrapping="WrapWithOverflow" 
      Text="blah blah blah blah" /> 


</Canvas> 

屏幕截图

enter image description here

的诀窍是画布继承父容器和宽度身高从它的孩子。我正在考虑在自定义控件中包装模式。