Windows mobile autoresize with panels - c#

I've got an app which will run on two different devices - one with a screen size of 240x320, the other 480x640.
For all forms bar one the VS generated code is fine:
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScroll = true;
For one form i'm capturing a signature. I'm doing this by a panel with a graphics handler; capturing mouse down and move events; this generates a list of vector points which I can draw lines with.
On the smaller res screen this is fine. On the higher res, I can't display my lines.. and I think this is because the panel is beyond the windows form size.
The form is created with a size of 240 x 268; a standard size I think - i've not manually set it, VS does this for me.
In order to get the panel in the right spot on the high res device, the co-ordinates are 3, 290; ie, 290 is past 268. Also the width of the panel is 448 which is somewhat larger than 240.
I'm using .net 2.0 (can't use later). I think I need to resize the form to make it larger but I do want to keep the existing re-sizing for the other controls on the form.
I'm not sure how to do this.

Make the form dock to fill, then use the Anchor properties to ensure controls inside the form resize as expected.
If you want the option of customizing how an individual control resizes, then DONT set the anchor properties on it, and instead handle the Resize event and perform custom resizing/repositioning within code there.
eg
private void form_Resize(object sender, EventArgs e)
{
// Center the control without changing width. Other controls are anchored.
this.control.Left = (this.Width - this.control.Width) / 2;
}

I'm writing this answer for the benefit of those who may have a similar problem in the future. PaulG pointed me in the right direction but I found the root cause to be something else.
The PDA project i've got uses "FormFactor WindowsMobile 6 Classic" which has a default size of 240 x 268.
Changing this to "Windows Mobile 6 Professional VGA" created a much larger form size.
This allowed me to get things positioned correctly for the larger size; then AutoScaleMode to DPI; and manually resizing the panel smaller made it all work.
IE, going from larger to smaller was easy; I didn't get smaller to larger working.

Related

How to make a Windows Form responsive [duplicate]

I have read several stack overflow questions without finding a good working solution to my problem. How can I resize my controls whenever the form is resized? I would like them to get larger or smaller when the form becomes larger or smaller.
In visual basic this was quite easy to do with the form.Zoom property (which did't really require resizing controls of course, but solved what I needed). Unfortunately this is not available in C# winforms.
Here is some other things I have tried without luck:
private void formMain_Resize(object sender, EventArgs e)
{/*
double scale;
this.scaleWidth = (float)this.Width / (float)this.origWidth;
this.scaleHeight = (float)this.Height / (float)this.origHeight;
if (this.scaleHeight > this.scaleWidth)
{
scale = this.scaleHeight;
}
else
{
scale = this.scaleWidth;
}
foreach (Control control in this.Controls)
{
control.Height = (int)(control.Height * this.scaleHeight);
control.Width = (int)(control.Width * this.scaleWidth);
this.Refresh();
// control.Font = new Font("Verdana", control.Font.SizeInPoints * heightRatio * widthRatio);
}
///////This scaling didnt work for me either
//this.Scale(new SizeF(this.scaleWidth, this.scaleHeight));
//this.Refresh();
*/
}
If I overlooked an actualy working sample of code on another stack overflow question I would love to see it, but the ones I found were similar to those above which are not working.
Perhaps I was misusing it and someone could post sample code to show for those of us who keep asking this question how to go about solving the problem.
Also, I have tried using some of the anchor/docking tools thinking they would automatically allow it but it didn't.
The best option is to use a TableLayoutPanel. Put TableLayoutPanel on the form, set the Dock property to Fill, create required rows and columns and put the controls inside the cells. Of course you need to set Dock/Anchor on the controls inside the cells, so they respond to changes to the cell size. In some situations you may need to put a Panel into a cell and drop the controls inside it, because every cell can only contain a single control. You may also need to set RowSpan/ColumnSpan on the controls.
By using a TableLayoutPanel, you have complete control over how your cotrols should be arranged. You can set absolute or percentage size for rows and columns.
Use Anchor of the control. There's an option on anchoring the top, bottom, left and right. And you're good to go.
I found an alternative solution that is working well for me, appreciate any negative or positive comments on the solution.
Using several Split Containers and Split Containers inside of Split Containers in different regions I am able to section off the primary pieces of the layout, and within there utilizing Docking and Anchoring I am able to accomplish exactly what I wanted to do - it works beautifully.
I would point out I am aware that some folks online mention split containers use lots of resources.
If your controls are in a group box, be sure to set the group boxes properties to resize. Controls inside the box are controlled by the box. The box size (unless it is inside another box) is controlled by the form.
What you are trying to do in your code is to change the sizes of the controls which isn't so good approach. Generally, the size of the Buttons and TextBoxes shouldn't be changed when you re-size your form, but they often need to move (change location). Some controls do need to change size according to the re-sized form and but in most cases only one dimension. The central controls that are used for working area (if you are developing the tool for drawing for instance) should change sizes of both dimensions. All this you can accomplish by properly setting Dock and/or Anchor properties of the controls.
textBox1.Dock = DockStyle.Bottom;
textBox1.Anchor = AnchorStyles.Bottom & AnchorStyles.Left;
All these are also easily set in the Properties panel when using designer.
But if that isn't enough for you, in rare cases, you will most definitely want to only change the location of the control:
textBox1.Location = new Point(newX, newY);

Winform size and location of winform on screen regardless of resolution

I have a winform (c#, let's say 250px by 250px) that needs to stay in one location on the screen regardless of screen resolution i.e 800x600, 1920x1080 etc. The Winform itself contains only one element - a picturebox so what's inside really doesn't matter (no need to worry about fonts, etc.). I just need it to stick in one place on the screen from one monitor to another.
Any ideas? Thanks in advance.
Could you use one of these?
1) WindowsState = Maximized (then you dont worry, it always takes whole screen)
2) StartPosition = CenterScreen (then it always shows as centered), or CenterParent to center within parent form
3) Location = in this case you would have to do some math to get screen size, your form size than based on that center it but I dont see point of using this considering that StartPosition does it already for you.
Hope that helps
Ok, so in order to get the window at a fixed location given in % of the screen size, you need the screen size (e.g. using this answer), compute the desired position, and set it as the window-location.
Since you need to do it at startup, you could do it before you show the window, or maybe best inside a Frame.Loaded event handler.

Switched to VS 2012 and now form doesnt resize properly?

I switched to VS 2012 yesterday from VS 2010 and all seemed to go well except this.
I have a button on my form that when pressed extends the width of the form to show additional controls. Press the button again and it reduces the width to hide those controls. Now all of this worked great in VS 2010 and also works fine when I debug in VS 2012 but as soon as I publish or compile the project and open the .exe when you click on the button it adds like 5 to the width instead of the 100+ it needs to. I click it again and it will then change it to 372 like it should and shows all my controls. I click it again to hide the controls and it hides the controls partially (goes to the 188 + the mysterious 5) I hope all of this makes sense and am hoping there is a better way to run the process I need to.
Here is the code I am currently working with and I didn't change anything between switching from 2010 to 2012. In fact, if I open this same solution in 2010 and publish everything works fine.
private void button1_Click(object sender, EventArgs e)
{
if (this.Width == 188)
{
this.Width = 372;
this.Height = 540;
progressBar.Value = 100;
copied_status.Text = ("Output View Enabled");
}
else
{
progressBar.Value = 100;
copied_status.Text = ("Output View Disabled");
this.Width = 188;
this.Height = 540;
}
if (this.Width == 372)
{
button1.Text = "<<";
}
else
button1.Text = ">>";
}
The width of your form hasn't been 188 pixels in a long time. Now with VS2012, Windows finally stops lying about it.
At issue are the fat window borders in Aero. They were an extreme appcompat problem when the feature was introduced in Vista. Very necessary because those two pixels where getting hard to hit with a mouse. But drastically incompatible with the way an application creates a window. It asks for a specific window size, the outer size, the nWidth and nHeight arguments of the CreateWindow() function. But what really matters is the size of the client area, the part of the window inside the borders. If Microsoft wouldn't have done something about it, old applications would have ended up with a client area that was too small. Which looks very bad, the window content would not fit anymore. A control towards the bottom or right side of the form would not be completely displayed for example.
So, sneakily, Aero makes the window larger by the extra width of the fat borders. And when the app asks for the window size, it sneakily says that it is smaller by the same added width. The app doesn't know any better than it is still running with the same window size it had on XP. This works pretty well, but is not exactly ideal. Hard to get window edges to align properly with that lie for example.
Whether or not Aero will lie about the window size is based on the target operating system recorded in the EXE header. When it sees a version older then 6.00, the Vista version number, then it will assume that your EXE is a legacy program that doesn't know about the fat border feature. So needs to be lied to. You've been running with that target version number set to 4.00 for a long time, it is written by the .NET compiler when it builds your program. You can see it with dumpbin.exe /headers yourapp.exe.
This finally changed in VS2012 and .NET 4.5. Which is a .NET version that is not available in XP. The compiler can finally make the hard assumption that XP is history and you are going to run on a version of Windows that supports Aero. So it sets the target Windows version in the EXE header to 6.00. Correspondingly, Aero will now stop lying about the window size. You get the real one, not the faked one.
So a quick fix is to change the target .NET framework version to 4.0. That's available on XP so you'll get lied to again.
Of course it is better to fix your code. Never use the Size, Width or Height property, they'll inevitably depend on the border and caption size. Use the ClientSize property instead, that's the stable one and the one you really care about. But be careful with that property as well, a form may rescale when it runs on a machine that has its video adapter set to more than 96 dots per inch. Another feature that's very accessible in Vista and up. Rescaling changes the ClientSize proportionally by the DPI setting.
The real fix is to use a bool field instead that keeps track of the window state. And set the ClientSize property based on the position of a control you want to hide or reveal. So roughly:
private bool enlarged;
private void button1_Click(object sender, EventArgs e)
{
enlarged = !enlarged;
int width = someControl.Left - 5;
if (enlarged) width = someControl.Right + 5;
this.ClientSize = new Size(width, this.ClientSize.Height);
}
Replace someControl in this code with the name of your controls.

Resize Controls with Form Resize

I have read several stack overflow questions without finding a good working solution to my problem. How can I resize my controls whenever the form is resized? I would like them to get larger or smaller when the form becomes larger or smaller.
In visual basic this was quite easy to do with the form.Zoom property (which did't really require resizing controls of course, but solved what I needed). Unfortunately this is not available in C# winforms.
Here is some other things I have tried without luck:
private void formMain_Resize(object sender, EventArgs e)
{/*
double scale;
this.scaleWidth = (float)this.Width / (float)this.origWidth;
this.scaleHeight = (float)this.Height / (float)this.origHeight;
if (this.scaleHeight > this.scaleWidth)
{
scale = this.scaleHeight;
}
else
{
scale = this.scaleWidth;
}
foreach (Control control in this.Controls)
{
control.Height = (int)(control.Height * this.scaleHeight);
control.Width = (int)(control.Width * this.scaleWidth);
this.Refresh();
// control.Font = new Font("Verdana", control.Font.SizeInPoints * heightRatio * widthRatio);
}
///////This scaling didnt work for me either
//this.Scale(new SizeF(this.scaleWidth, this.scaleHeight));
//this.Refresh();
*/
}
If I overlooked an actualy working sample of code on another stack overflow question I would love to see it, but the ones I found were similar to those above which are not working.
Perhaps I was misusing it and someone could post sample code to show for those of us who keep asking this question how to go about solving the problem.
Also, I have tried using some of the anchor/docking tools thinking they would automatically allow it but it didn't.
The best option is to use a TableLayoutPanel. Put TableLayoutPanel on the form, set the Dock property to Fill, create required rows and columns and put the controls inside the cells. Of course you need to set Dock/Anchor on the controls inside the cells, so they respond to changes to the cell size. In some situations you may need to put a Panel into a cell and drop the controls inside it, because every cell can only contain a single control. You may also need to set RowSpan/ColumnSpan on the controls.
By using a TableLayoutPanel, you have complete control over how your cotrols should be arranged. You can set absolute or percentage size for rows and columns.
Use Anchor of the control. There's an option on anchoring the top, bottom, left and right. And you're good to go.
I found an alternative solution that is working well for me, appreciate any negative or positive comments on the solution.
Using several Split Containers and Split Containers inside of Split Containers in different regions I am able to section off the primary pieces of the layout, and within there utilizing Docking and Anchoring I am able to accomplish exactly what I wanted to do - it works beautifully.
I would point out I am aware that some folks online mention split containers use lots of resources.
If your controls are in a group box, be sure to set the group boxes properties to resize. Controls inside the box are controlled by the box. The box size (unless it is inside another box) is controlled by the form.
What you are trying to do in your code is to change the sizes of the controls which isn't so good approach. Generally, the size of the Buttons and TextBoxes shouldn't be changed when you re-size your form, but they often need to move (change location). Some controls do need to change size according to the re-sized form and but in most cases only one dimension. The central controls that are used for working area (if you are developing the tool for drawing for instance) should change sizes of both dimensions. All this you can accomplish by properly setting Dock and/or Anchor properties of the controls.
textBox1.Dock = DockStyle.Bottom;
textBox1.Anchor = AnchorStyles.Bottom & AnchorStyles.Left;
All these are also easily set in the Properties panel when using designer.
But if that isn't enough for you, in rare cases, you will most definitely want to only change the location of the control:
textBox1.Location = new Point(newX, newY);

Maximum window size changes from PC to PC

I created a small test application which allows very limited functionality of copying files from one place to another. Now due to the limited functionality, I kept the window size fixed (having maximized as false and well defined height and width of 250x200 pixels). Just 2 file browse elements and a Copy button.
My friends test ran it on their PCs and the problem is that it ran all well for most of my friends, however 3 of them noticed that the height of the application was not enough and the copy button was 80% hidden (only 20% of it was visible). One of them was on a 1920x1080 resolution and the other 2 were on 1366x728. And all the test PCs were Windows 7 computers.
How and why would this possibly happen?
One thing that I can think of one is their DPI setting's are different than your computer.
Control Panel\Appearance and Personalization\Display
having maximized as false and well defined height and width of 250x200 pixels
That's fine, as long as you set this size only in the form constructor. And set the FormBorderStyle to Fixed so it is clear that the window cannot be resized. If you do it later, like in the Load or Resize event then you'll displease users that have a nice high-resolution display. Or a "retina" display, we'll all have them soon. They need to bump up the video adapter's dot-per-inch setting so they can still read 8 point text without a magnifying glass.
Which causes text to get rendered with more pixels. Which requires that your controls get bigger, their sizes are specified in pixels. If you don't let them grow then you'll have small controls with big text, unattractive and unreadable. Bigger controls in turn requires that they move and that your form gets bigger so it still fits the controls.
This is all automatic, thanks to the form's AutoScaleMode setting. It defaults to Font which is just what you need. But that can't work when you force the form back to its original design size, it will clip the moved controls.
A quick way to check if your form still works properly on such a machine, other than tinkering with the video dpi setting, is this bit of test code in the Load event handler:
protected override void OnLoad(EventArgs e) {
this.Font = new Font(this.Font.FontFamily, this.Font.Size * 125 / 96f);
base.OnLoad(e);
}

Categories

Resources