I have a number of situations where I have panels or grids that resize automatically, but if they contain a TextBox
with TextWrapping="Wrap"
, the TextBox
continues to expand the panel/grid to the right long before it really needs to, such as the image below:
What I am looking to do is to have the TextBox
fill its area by wrapping text before it tries to expand to the right. A simplified example of the issue is:
<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>
I found a similar question on Stack Overflow here, but the best solution posted did not allow the TextBox
to expand. That solution was something like:
<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>
Any ideas other than extending TextBox
with modified behaviors?
There's a simple trick to get it working. Use a Canvas and then bind the width of the textbox to the actualwidth of the canvas and the height of the canvas to the actualheight of the textbox.
<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>
Screen shots of our production app using it
and resized
The trick is that the Canvas inherits the width from the parent container and the height from it's child. I'm considering wrapping the pattern in a custom control.
Although I wouldn't recommend doing this as I think it introduces unexpected behavior to the user, this seems to achieve what you're asking:
XAML:
<TextBox ... MinHeight="120" Width="200" SizeChanged="TextBox_SizeChanged" />
Code behind:
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;
}
}
A couple of things to note, 1) in order for this to work you must both a MinHeight
and Width
to allow for expansion and 2) the horizontal expansion of 20 is just an arbitrary value I used for testing purposes; you'll want to come up with a more reliable way of calculating a variable expansion value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With