Dynamic Winforms control changing size - winforms

I have this code
ShadedRoundedRectangle rect = new ShadedRoundedRectangle();
rect.Location = new Point( 0, nextY );
rect.Size = new Size( 200, 20 );
rect.NewText = String.Format( "{0} x {1} ({2} kcals)", ci.Amount, ci.Product.ItemName, ci.Amount * ci.Product.Calories );
panel1.Controls.Add( rect );
ShadedRoundedRectangle is a user control that draws a shaded rounded rectangle of size 200,20 as you can see. When adding rect to the panel controls collection the size changes to 233, 23.
The user control has 0,0,0,0 defined for both padding and margin properties and I am stuck as to why this is happening.

I am answering my own question as I have found out what was causing the Size property to change, after adding the user control to the panel's controls collection.
Changing the user control's default font of MS Sans Serif 8.25pt to a different font, i.e. Arial Regular 8.25pt in this case resolved my issue and the size didn't change after the user control was added to the panel's controls collection.
There must be some bug that exists within Visual Studio 2012 that causes this behavior to happen.

The real problem is the AutoScaleMode property. By default it is set to Font, which means that if the font size of the form is different from the font size of the control, the control will be resized.
Setting the AutoScaleMode to None, will solve this issue.
Also, making sure the form and the control have the same font will solve this issue.

Related

WPF giving incorrect size values

I have a WPF application in which I am attempting to take a screen grab of a WindowsFormsHost control. To do this I am doing a Graphics.CopyFromScreen. On most boxes we have tested on this works perfect, however we have one machine that is not grabbing the right size values. The width and height that are given by WPF do not match the actual width and height of the control. When snooping, the incorrect values show for the ActualWidth and ActualHeight of the control as well. Even further, when I snoop the main window (which is maximized), I get an ActualWidth of 1550 and and ActualHeight of 840, but my screen resolution is 1920x1080. I would understand being a few pixels off for borders, margins, etc, but to have WPF tell me my maximized window is 370 pixels shorter in width than the actual screen just doesn't make sense. Can anyone explain this behaviour?
The following is the code being used to capture an image of the control:
public static Bitmap CreateBitmapFromVisual(this FrameworkElement target)
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
if (bounds.Width == 0 && bounds.Height == 0)
return null;
System.Windows.Point p0 = target.PointToScreen(bounds.TopLeft);
System.Drawing.Point p1 = new System.Drawing.Point((int) p0.X, (int) p0.Y);
Bitmap image = new Bitmap((int)bounds.Width, (int)bounds.Height);
Graphics imgGraphics = Graphics.FromImage(image);
imgGraphics.CopyFromScreen(p1.X, p1.Y, 0, 0, new System.Drawing.Size((int) bounds.Width, (int) bounds.Height));
return image;
}
Here is an image to better describe what I'm talking about:
As you can see, snoop is saying that the actualwidth and actualheight of the WindowsFormsHost is 486x336. Any debug information I log says the same thing. However, when I Print Screen and crop to the control in paint, the actual size is 608x423, a sizeable difference.
As a further update, it seems like the width given by wpf is roughly 80% of the actual width. This is true for both the control and the window.
Have you looked at your DPI settings for your display?
To do this go to Control Panel - Display and select Set custom text size (DPI). In the dialog that opens you will see a scale to percentage. If it is not set at 100% then try this. This could be your issue.

WPF PreferredSize property?

In Windows Forms, you have a PreferredSize property that will tell you how large a control would like to be.
Where's that property in WPF?
I have a Grid with some content (of unknown size) and would like to create an animation that increases the grid in height from 0 up to its preferred (auto) height. Of course the grid is either at 0 height or collapsed at the beginning, because it's not supposed to pop up in an instant but smoothly "fade in". So I cannot use the ActualHeight property for the animation target because it is always 0. The opposite direction animation should be easier because I can animate from ActualHeight (or just no explicit start value) to 0.
Given a FrameworkElement (element) and I wish to allow it to expand fully and then measure it's size I do the following:
element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
element.Arrange(new Rect(new Point(0, 0), element.DesiredSize));
element.UpdateLayout();
Size sizeElementWantsToBe = element.DesiredSize;
Caveat: I found this question because I'm having problems with this method of triggering layout with Telerik RadGridViews with templated columns. But I doubt you will have that problem.
Hope this helps.

Sizing WPF windows automatically

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;

Form height problem when FormBorderStyle is NONE

I have a borderless form (FormBorderStyle = None) with the height of 23 pixels (set in the designer)
When .NET draws my form at runtime - it draws it 38 pixels high (it adds the height of a title-bar for some reason).
MessageBox.Show(this.Height.ToString()); //this shows 38!! why?
To work it around I have to set "Height = 23;" in the Form_Load event.
private void MyForm_Load(object sender, EventArgs e)
{
this.Height = 23; //workaround. wtf??
}
You can try this yourself in Visual Studio 2010 (Winforms App, target Framework - 2.0).
Wtf?
Yeah, it is a bug, of sorts. Note how in the designer you set the size of the form with the Width and Height properties. Those properties include the size of the borders and the title bar. That's a problem however, your form may run on a machine where the user has increased, say, the title bar font size. That then would reduce the size of the window's client area. Or in other words, the form's ClientSize property would change on that machine. Leaving less room for the controls and messing up the design of your form pretty badly.
There's code inside the Form class that runs after the Handle is created, right before the Load event runs. It recalculates the Size of the form, using the same ClientSize you had on your machine. Now everything is good, the Height of the form won't match the one you set in the designer but the form otherwise looks the same and the layout of the controls is identical.
That same code also ensures that the window doesn't get too small. And that's where it falls over, it doesn't pay enough attention to the FormBorderStyle property. Clipping the height to the title bar size plus the client area height, as you found out. It also prevents the form getting too narrow, trying to make sure that the icon and min/max/close buttons are always visible. Even if you don't have any.
The workaround is to change the ClientSize after this code runs, the OnLoad override or Load event handler is the right place for that. Beware that if you hard-code the form size like this then you should also set the AutoScaleMode property to None. Make sure that this doesn't cause trouble on a machine that has a different DPI setting.

How to determine width of a windows forms controls whose width was increased because it is Anchored?

I currently have a Textbox on a Windows Forms, and I need to dynamically add a PictureBox box control at the right of the Textbox.
I create the PictureBox programmatically and I when setting the location of the PictureBox, i'm setting like this:
pBox.Location = new Point(tbControl.Location.X + ctrl.Width, ctrl.Location.Y);
So i'm setting the picture box to be located at the X location of the textbox PLUS the width of the textbox. However, since the textbox has an anchor property set to right, its width increases to fill the space between itself and the form border.
Problem is, that even though the textbox's width is visually bigger than the actual value of Textbox.Width. the Width property is not taking into account the extra width of being anchored.
I already tried properties like Textbox.Bounds.Width, Textbox.ClientSize.Width, Textbox.DisplayRectangle.Width, etc. with no luck. All of those properties return the original Width of the control without taking into account the resized width due to the Anchor property.
Does anyone know how I can determine the real size of the textbox? Thank you
The Width property always tracks the current width of a control, whether it is anchored or not. However, the TextBox is going to grow when you make the container larger and that will make it overlap the PictureBox. You have to anchor the PB to the right as well.
These should be returning the adjusted size. Either you are referring to the wrong textbox, or you are doing the query before the size has actually changed.

Resources