我有很多情况下我有自动调整大小的面板或网格,但如果它们包含TextBox
和TextWrapping="Wrap"
,那么TextBox
会在它真正需要之前将面板/网格继续向右扩展,如下图所示:
我想要做的是让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>
我在Stack Overflow here上发现了类似的问题,但发布的最佳解决方案不允许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>
除了用改进的行为扩展TextBox
之外的任何想法?
虽然我不建议这样做,因为我认为它会给用户带来意想不到的行为,但这似乎达到了你所要求的:
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)为了使其工作,你必须同时使用MinHeight
和Width
进行扩展; 2)20的水平扩展只是我用于测试目的的任意值;你想要提出一种更可靠的计算变量扩展值的方法。
有一个简单的技巧让它工作。使用Canvas,然后将文本框的宽度绑定到画布的实际宽度,将画布的高度绑定到文本框的实际高度。
<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>
使用它的我们的生产应用程序的屏幕截图
并调整大小
诀窍是Canvas继承父容器的宽度和子容器的高度。我正在考虑将模式包装在自定义控件中。
我现在要解决的解决方案是上面提到的边界技巧,并解释了更好的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>