views:

463

answers:

2

Hi All,

Was just wondering how I would go about letting the user resize a TextBox control at runtime by dragging its corners in WPF. Less importantly, is the same technique used for the resizing of all controls?

Thank you :)

+4  A: 

You should try setting the textbox's alignments to stretch and placing it inside a container that you can resize, like a grid with gridsplitters (or in a resizeable window). It's much easier than trying to create a custom resizeable textbox, and it will work better with the rest of your layout.

EDIT: Here's an example from a real app:

<Grid>...
<GridSplitter Grid.Row="1" Grid.ColumnSpan="2" ResizeDirection="Rows" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="4" BorderThickness="0,0,0,1" BorderBrush="Gray" Background="Transparent"/>
<TextBox Grid.Row="2" Grid.Column="0" Margin="6,6,6,6" Name="RequestTextBox" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" Text="{Binding Request, Mode=TwoWay}"/>
<GridSplitter Grid.Row="2" Grid.ColumnSpan="2" ResizeDirection="Rows" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="4" BorderThickness="0,0,0,1" BorderBrush="Gray" Background="Transparent"/>
...</Grid>
Eric Mickelsen
It's possible that this isn't perfect for your case, but it should be the first thing you consider.
Eric Mickelsen
Interesting, I am tryin' that out now! :-) +1
lucifer
+2  A: 

tehMick's answer is absolutely correct: You should definitely create a container to do the resizing rather than customizing the TextBox itself. And if it works for you GridSplitter is a very good in-the-box solution.

I had the same situation but GridSplitter wouldn't work, so I created a "ResizeBorder" control that handled mouse drags on its four corners to resize in two dimensions, or the middle of the sides to resize in one. This is actually very simple code: Just handle MouseDown, set a local variable giving the MouseDown location and the side/corner being dragged, then on MouseMove update the size.

My ResizeBorder was stylable so I could show just four boxes at the corners and lines on the sides, or anything more complex that I could dream up.

Also, note that whether you are using a Grid and GridSplitters or a ResizeBorder or anything else, you have the choice of putting your resize functionality either around the control like this:

<my:ResizeBorder ...>
  <TextBox ... />
</my:ResizeBorder>

or by updating the ControlTemplate for TextBox itself:

<ControlTemplate x:Key="ResizableTextBox" TargetType="{x:Type TextBox}">
  <my:ResizeBorder>
    ...
  </my:ResizeBorder>
</ControlTemplate>

...

<TextBox Template="{StaticResource ResizableTextBoxTemplate}" ... />

The advantages of this latter method are that you can use a style or attached property to make may TextBoxes resizable and that you can easily change the resizability of the TextBox dynamically in code.

Ray Burns
Those are good options +1
Eric Mickelsen