Sizing WPF windows automatically - wpf

When designing WPF dialog windows in the XAML designer (that are not manually resizeable by the user), the windows automatically resize to fit their content, and everything is fine. But when I run my app, the windows become huge and there's a lot of empty space.
I know this is a "feature" of WPF that can be "fixed" by setting the SizeToContent tag, but another issue arises when I do this: If the window contains a textbox, for instance, and the user enters data that overflows the visible area, the window will stretch to accommodate it. This happens with listboxes, treeviews, you name it.
All I want is for Visual Studio to figure out the ideal window size that it shows me at design time, then set the window to be that size at runtime, and don't change the size after that. It seems like this should be an easy thing to do.
Edit: Figured out part of the problem: I have controls set up in a grid, and the column's width is set to "Auto" which is why everything is resizing.

Use View Box
The ViewBox is a very useful control in WPF. If does nothing more than scale to fit the content to the available size. It does not resize the content, but it transforms it. This means that also all text sizes and line widths were scaled. Its about the same behavior as if you set the Stretch property on an Image or Path to Uniform.
Although it can be used to fit any type of control, it's often used for 2D graphics, or to fit a scalable part of a user interface into an screen area.
<Viewbox>
<Enter your code/>
</Viewbox>

Try setting the window's height and width to Auto. Also, remove the SizeToContent attribute. This should fix it.

I do not think that this is this is something which is commonly requested so it's probably not easy to do, one method i can think of would be starting with automatic SizeToContent and handling the Loaded event and setting:
Height = ActualHeight;
Width = ActualWidth;
SizeToContent = System.Windows.SizeToContent.Manual;

Related

How to scale form with font size in WPF?

How can i scale a Form with font in WPF?
i.e. What is the WPF equivalent of
this.Font = SystemFonts.IconTitleFont;
In WinForms, if you're a good developer, you honor the user's font preferences. A WinForm that starts out as:
You then apply the user's font preferences:
this.Font = new Font("Segoe Print", 11, GraphicsUnit.Point);
and elements on the form scale to accommodate the new size:
Notice:
the form is wider and taller
the label is positioned further down, and to the right
the label is wider and taller
the text of the label is not cut off on the right or on the bottom edge
the button is wider and taller
but button is positioned further down, and to the right
Note: In WinForms you can also use the line:
this.Font = SystemFonts.IconTitleFont;
WPF doesn't support Font, which is why i provided the clearer alternative. For the example below.
A similar WPF form starts out as:
You then apply the user's font preferences with:
this.FontFamily = new FontFamily("Segoe Print");
this.FontSize = 14.666; //11pt = 14.66
and elements on the form don't scale to accommodate the new size:
Notice:
the label's position has not changed
the button's position has not changed
the form is not wider or taller (text is cut off)
the label is not any wider (text is cut off on the right)
the label is not any taller (cutting off text along the bottom edge)
the button is not any wider (text is cut off)
Here is another example of two buttons that are the same size:
WinForms:
Windows Presentation Foundation:
Bonus Reading
WPF: How to specify units in Dialog Units?
How to prevent WPF from scaling with the Windows font size options?
WPF version of .ScaleControl?
WPF doesn't do primitive font-based scaling because it's... well, primitive. You can see it in your own screenshots.
Here's your "WinForms, before changing font" screenshot. Take a look at how much space there is between "sat on a log." and the right edge of the form.
And here's your "WinForms, after changing font" screenshot. Notice how much less margin you have after "scaling".
If you hadn't left all that extra space, then your label would be cut off with the new font. And with some fonts, it would be cut off even though you did leave all that extra space. That's what I mean when I say WinForms' scaling is "primitive". WinForms picks a single scale to apply to everything, and that scale is not chosen with any awareness of your content; it's based on average statistics for the font, which can and will fall apart once you start talking about specifics.
WPF doesn't hobble you with something that primitive. It gives you an amazingly powerful layout system, where it would be trivial to make a window that scales beautifully. But instead, you're choosing to cripple that layout system by using hard-coded sizes. Stop it.
Hard-coded sizes have two huge problems:
They don't adapt to different fonts. You've noticed this already.
They don't adapt to different content. (What happens when you want to make a German version of your app, and the German text doesn't fit into your hard-coded button size?)
Hard-coded sizes just don't adapt. To anything. You had to use them in WinForms because that's all WinForms supported. But WPF gives you a proper layout system, so you don't have to (and shouldn't) use anything that crude.
All you need is this:
A Window with SizeToContent="WidthAndHeight". That way, the window will be exactly the right size to accommodate the text and button, no matter what font or language you use.
Since you only have two UI elements, and one is above the other, you would put a StackPanel inside your Window.
Inside the StackPanel, you need:
A Label or TextBlock to show your text, with the text in Content (Label) or Text (TextBlock); and
A Button with HorizontalAlignment="Right", and the text in Content.
Set some Margins on the StackPanel, TextBlock, and Button to space things out to your liking.
That's it. Don't set any other properties on anything -- especially not Width or Height.
Now, if you change your font, the window and the button will still be exactly the right size, and won't cut off your text. If you localize your app into a different language, the window and the button will be exactly the right size, and won't cut off your text. Stop fighting WPF, and it will give you great results.
If you later want to make your layout more advanced, you could consider things like:
If you want the button to be a little wider (to have more breathing room before and after the text), try playing with the Padding, or set a MinWidth and MinHeight. (Don't use Width or Height if your button contains text. You might consider using them if your button only contains an image, but maybe not even then.)
If you're worried that the font might make the window so large that it no longer fits on the user's screen, and want to enable word-wrapping, then play around with MaxWidth and TextWrapping.
WPF's layout system is amazingly powerful. Learn it. Don't fight it by using hard-coded layouts and then complaining that your hard-coded layouts suck.

Scale usercontrol in wpf ? vertical and horizontal scrollbars

I implemented a usercontrol, but i have a problem with rescaling the window. I know when i make the window smaller, everything scales, and every textbox and label becomes also smaller. But this is not what i want, i just want that when i make the screen smaller, everything stays the same size, and that scrollbars appear ( vertical and horizontal ). How do i do that?
Thanks
Assumption
The behaviour you describe, is not mandatory the default layout-behaviour of WPF. It depends on the layout-controls you use. I assume, you're using a Grid with setting it's columns and rows to the Start (*)-GridLengths. This would have more or less such an effect as you describe (without scaling). Or maybe you are using a ViewBox, this control scales the whole content based on the available layout size.
Solution
I guess that wrapping your whole content into a ScrollViewer will probably do what you desire. If not, I suggest that you post some XAML-code to show us how you have built your content.
<ScrollViewer>
<YourContent>
</YourContent>
</ScrollViewer>
Update
If you really scale your window (applying a ScaleTransformation) and you want your UserControl to be the only control within that does not scale, you have to scale your UserControl in the opposite direction as you have done it with your window. Apply a ScaleTransformation and set the scale values to 1/scale. Or try to use the ViewBox to blow up the content of your UserControl, but this will not be very exact.

How to resize multiple WPF controls when the text size changes?

What's the correct pattern to resize controls when a font size changes?
For example, I used the WPF designer to make a form, and placed UI elements from the toolbox. Late in the game I got the requirement that the font size of every UI element needs to be configurable, so now I'm thinking there has to be a better way to resize controls when the font size changes. Right now I'm doing alot of code behind calculations on Margin properties.
For such cases I usually place my control inside Grids and StackPanels, this way font size won't affect the layout, everything will be stretchable.
Never place controls on the Window using absolute coordinates.
Make sure your Height and Width on the controls are set to Auto.
When you use the designer/toolbox to add controls it usually provides a static height/width. If you type the tag in the XAML editor you get the control default which is usually Auto.
You'll notice the black diamond in the property window next to the attributes that are changed from their default value. You can right click and choose reset value to clear the attribute from your XAML and see what the default value is.

Silverlight 4/WPF - Nested ScrollViewer panel that scales with available screen size

In the Windows Forms world you can take a panel and set it's dock property to fill and so on with nested panels, when the user resizes the window the panels and nested panels automatically resize too. I want to achive something similar with Silverlight, here is my current structure.
Main
ScrollViewer // for body
UserControl
Grid
control
Scrollviewer // this is where my problem is
Control
The problem is I can set a size for the nested scroll viewer that looks good for 1024 resolution, but I also want to account for users that have larger resolution. If I leave it auto the content just stretches below the visible bottom line and defers to the top level ScrollViewer.
If I could achieve something analogous to how Windows Forms handles this with docking I think my problem would be solved. I must have a ScrollViewer for the nested panel and I want it to fill all visible space left. How Can I achieve this with SL4 or WPF?
[Edit]
Here is an illustration of what i'm after.
The top-level ScrollViewer allows its content to be as large as it needs to be, and adds scrollbars if that means they don't fit in the window. Its children no longer know or care how tall the window is; they just know that they've got as much space as they want.
So what is it that you want from your nested ScrollViewer? It's got all the space it needs, so it will grow to show all of its content -- there's nothing to restrict it to the height of the window. In fact, you added a top-level ScrollViewer, which specifically told it "don't restrict it to the height of the window".
If you want your inner ScrollViewer to be restricted to the window height, then take out the top-level ScrollViewer.

WPF - UserControl sizing on Custom Canvas

I have a custom canvas that I can drop controls on, move, and resize. I need to be able to at least start with a pre-determined size but then allow re-sizing.
My problem is that I have a user control that doesn't appear to resize. I set Height and Width on the user control (works on drop). But then as the control is resized on the canvas the visual size stays the same (the sizing handles are changing). I can see the Height property changing (usercontrol.height) as the control is resized. But again, the appearance of the control stays the same size.
I had a thought that the inner container on the user control should be bound to the usercontrol.height but that didn't seem to help. (or maybe I didn't have the binding right).
On the same canvas, if the dropped control is for example, an Image control, I can set an explicit height on the drop and everything resizes as it should. So it seems to be UserControl thing.
So is there something special I need to do with UserControls to get the visuals to resize? Should I be using explicit height and width to get it all started?
Thanks for any help.
The WPF layout system can be confusing, as you've discovered. There is no substitute for a solid understanding of the layout and measurement system. If you plan on doing much WPF development, it's worth taking 20 minutes to read this article on the layout system and then experimenting for a while in an iterative environment such as Kaxaml until you feel comfortable.
The system is very logical. It won't take long for the penny to drop. Sorry for the indirect answer, but I don't believe there's enough information in your question to really explain what's going on.
You might also look at the HorizontalAlignment and VerticalAlignment properties.
Not a WPF expert but I believe you need to enable auto-sizing in order to achieve the scenario you are looking for. This is done by setting the Height/Width of a control to Double.NaN which essentially says, "I have no specific size". Once you do that, the control should resize to occupy available space based on the need of the control.

Resources