Silverlight resize textbox according to text size - silverlight

I'm using Silverlight 4 and I want to create a childwindow with a TextBox, that the TextBox's width will be constant and it's height will be resized according to the size of the assigned text.
Any ideas how can I do it?

Set the Width property on your textbox to whatever you want it to stay at -- then set the TextWrapping property to "Wrap", and then make sure the content control holding is not set up to stretch it vertically and it will do what you want (text wraps and the box grows vertically to contain it as you enter stuff).
Ultra simple example:
<Grid x:Name="LayoutRoot" VerticalAlignment="Top">
<TextBox Name="tbTest" TextWrapping="Wrap" Width="300" />
</Grid>

Related

Max Height for a dynamically sized WPF Textbox

I'd like to make a TextBox in XAML that is dynamically sized to the content, but that has a max height that keeps it from growing forever if that text is very long. If that max height is reached, the TextBox should stop growing and instead show a scroll bar. Ideally, that scrollbar does not exist when the text fits. How would I go about that?
I gain the dynamic resizing property by simply not setting an explicit Height on the TextBox (and possibly turning on text wrapping). But achieving the max height and scroll bar is a mystery to me.
Currently I have a setup that always shows a scroll bar and that grows forever. How would I change this?
<ScrollViewer>
<TextBox Text="{Binding Path=Selection.SummeryDescription, UpdateSourceTrigger=PropertyChanged}" />
</ScrollViewer>
You can do that just by setting the ScrollViewer.VerticalScrollBarVisibility to Auto and the MaxHeight. See example below:
<TextBox Text="..." TextWrapping="Wrap" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="500" />
This will only show a vertical scrollbar when needed.
Please notice that in my example the ScrollViewer element is omitted as I enable the ScrollViewer via the ScrollViewer.VerticalScrollBarVisibility property instead.

Why is my Grid's width NaN?

I have the following mark-up in a view. When I get WindowContainer.Width during start-up code for the view, it returns NaN.
<Border BorderThickness="10">
<StackPanel x:Name="Panel" Orientation="Vertical" >
<Grid x:Name="WindowContainer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Loaded="WindowContainer_OnLoaded">
<delphi:Win32WindowHost x:Name="Host" />
</Grid>
<TextBlock x:Name="InfoTextBlock" HorizontalAlignment="Right" />
</StackPanel>
</Border>
Does Stretch make the grid stretch to accomodate all its content, or to fill its container? I want it to stretch to fill the container, the Border, and have a proper double width I can use to size a floating window to be the same size.
Does Stretch make the grid stretch to accomodate all its content, or to fill its container?
From MSDN about HorizontalAlignment="Stretch":
Child elements are stretched to fill the parent element's allocated layout space. Explicit Width and Height values take precedence.
Why is my Grid's width NaN?
NaN is to mean "not set". FrameworkElement is the base class for many Controls in WPF and if you do not explicitly set the Height and Width properties then in the class constructor will be a default value of NaN.
When I get WindowContainer.Width during start-up code for the view, it returns NaN
In this case try get the ActualWidth, instead of Width, because:
ActualWidth property is a calculated value based on other width inputs, and the layout system. The value is set by the layout system itself, based on an actual rendering pass, and may therefore lag slightly behind the set value of properties such as Width that are the basis of the input change.

Have WPF Window resize automatically based on the remaining area in DockPanel

I have a scenerio where I want to dynamically render a custom form object. This form is similar to a WinForms form. It will display one of more button bars, buttons can only live within a button bar in our implementation, and numerous edit control that the user will use for data entry.
In rendering the form we have in a configuration file a row height and column width, both as a pertcentage of the application area. All forms share a common row height and column width. The actual device unit value of these are calculated on applicaiton initialization.
My issue is with sizing the form. For example, I have a form that is supposed to be 15 rows by 80 columns, let's say this translates to 500 units high and 800 units wide. This would be the form area, not including button bars. Right now I am calculating the window height and width in a FormPreviewManager. However, it is cumbersome as I have to give the total units, including the size of the button bar(s) and the windows borders, which may change as they have the option of including a title bar or not in the floating form window.
Within the rendering of the form I use a DockPanel to render the button bar(s) and claim the remaining space as my grid of rows and columns. I tried creatign the button bar(s), setting the remaining space to my FormGrid object, then specifically setting the Width and Height for the FormGrid but it doesn't change the size of the containing window.
How can I make it so that the floating window sizes automatically? I want to be able to draw the button bar(s) then say remaining space is 500 units high and 800 units wide, the window then adjust to whatever size it needs to hold this data, no more and no less.
Any help on this, or a possible other approach, would be great.
Update
Basically if this was my entire XAML definition for my window I would like to be able to set the width and height of UnusedContent and have the window resize accordingly.
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Top" Height="50" />
<StackPanel DockPanel.Dock="Left" Width="50" />
<ContentControl x:Name="UnusedContent" />
</DockPanel>
</Grid>
If I set UnusedContent to 200 by 200 it would create a window with interior dimensions of 250 by 250, the content area plus the two stack panels.
You can try placing a control to fill up the remaining DockPanel space, and then binding to that control's ActualHeight and ActualWidth properties
<DockPanel>
<StackPanel DockPanel.Dock="Top" Height="50" />
<StackPanel DockPanel.Dock="Left" Width="100" />
<ContentControl x:Name="Spacer" />
</DockPanel>
<Grid Height="{Binding ElementName=Spacer, Path=ActualHeight}"
Width="{Binding ElementName=Spacer, Path=ActualWidth}" />

WPF: view that scales to container at large sizes, scrolls at small sizes?

I am building a control depicting a diagram. The control's content (which is rather complex) will try to scale to fit allotted space to the extent possible. However, not all scales are valid. The content cannot shrink indefinitely. E.g. a box on a diagram should be at least 20 pixels wide. Thus, when the window is too small to fit the content even at the minimum size, scaling should stop and scroll bars must appear.
I cannot find an elegant solution for this in WPF. Any design ideas are greatly appreciated.
Set the Horizontal & VerticalAlignment of the content to Stretch but also set the MinWidth and MinHeight to appropriate values, place your content in a ScrollViewer whose Horizontal & VerticalScrollBarVisibility is set to Auto.
That should work, probably...
Example:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Button
MinHeight="400"
MinWidth="400"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Content="Buttons!"/>
</ScrollViewer>
</Window>

In XAML how to say: default width and height for e.g. TextBox

So I'm coming at WPF from a HTML perspective.
I just want to put a TextBox on my Window like this:
<Grid>
<TextBox Name="theName" />
</Grid>
Turns out that the TextBox is then HUGE, covers the whole window. (!)
Ok, that's not what I want, but I don't want to define the EXACT size either since I know Height and Width should be flexible, so I try:
<TextBox Name="theName" Width="Auto" Height="Auto"/>
Same thing. So I try:
<TextBox Name="theName"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
Same thing. So I just hard code the sizes:
<TextBox Name="theName" Width="100" Height="20"/>
Which I know is not a good programming practice in WPF.
So, what how do you tell TextBox to "display default sizes for the font size being used"?
You can take Bryan's example even a bit further. By specifying a specific alignment that isn't stretch and further constrain the TextBox so that it won't expand beyond a certain size. eg:
<Grid x:Name="LayoutRoot">
<TextBox HorizontalAlignment="Left" VerticalAlignment="Top" Text="TextBox" TextWrapping="Wrap"
MinWidth="15" MinHeight="20" MaxWidth="500" MaxHeight="50"/>
</Grid>
You can take it even further by setting up rows/columns inside the Grid and constraining them in various fashions. As you're coming from an HTML background, think of it like using a table to control layout. Remember that you can also nest other container objects (i.e. StackPanels, WrapPanels, other Grids, etc...).
The challenge with XAML and the WPF/Silverlight controls is that they a very flexible, so you've got to get a handle on all the options and how they affect layout.
Good luck. I'm going through this exact same thing now.
Use a different container.
The Grid always streches its child controls to fill the grid cell.
You could use e.g. a stackpanel which only streches its controls in one direction.
In addition to using a different panel as Stefan mentioned you could just give the TextBox an alignment that isn't Stretch. e.g.
<TextBox Name="theName" HorizontalAlignment="Left" VerticalAlignment="Top"/>
The sizes in WPF aren't pixels, they are "device independent pixels" that are 1/96 of an inch - so in today's normal DPI setup they map 1:1 to pixels.
But, if you run the program in high DPI mode the TextBox will grow with the DPI (and the font).
So setting an hard-coded size isn't that bad.
Other than that you can only use HorizontalAlignment and VerticalAlignment that are not "Stretch", this will size the TextBox to content - but then an empty TextBox will be tiny.
You can set VerticalAlignment to "Center", "Top" or "Bottom" to get automatic height of about one line (maybe backed up by a MinHeight setting to avoid problems really tiny fonts) and then set the Width so the TextBox width does not change as the user types into it.

Resources