Panel with fixed size - c#

I have a homework, where I need to create a winforms game using C#. I have the following components:
Panel subclass with custom paint event
Panel with default windows UI elements.
I want them to arrange like this:
Because I draw on the center panel manually, I want to set it's Width, and Height fixed, so the Form subclass, what will contain it, would show the whole panel.
I tried setting the size manually in the panel subclass:
Width = someFixedWidth;
Height = someFixedHeight;
Then adding it to the containing Form:
GamePanel panel = new GamePanel(...);
panel.Dock = DockStyle.Center;
this.AutoSize = true;
this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
this.Controlls.Add(panel);
Using this, I thought, that the form will respect the size of the Panel, but it just shrinks the window to so small, that nothing is visible, only the title.
So my question is, how would I be able to set the size of the GamePanel manually, and then dock it in the center of the form, so that the Form will respect the size I set, and doesn't makes it smaller/bigger?

The Dock property is used to define the behavior of the component during resizing Container (Form) The way you did the screen is not centralized but is resized according to the screen changes, the ideal is to use a method to reposition the control and set its size. See this:
SuspendLayout();
Width = someFixedWidth;
Height = someFixedHeight;
panel.Size = new Size(panelWidth, panelHeight);
panel.Location = new Point( ClientSize.Width / 2 - panelWidth / 2, ClientSize.Height / 2 - panelHeight / 2);
panel.Anchor = AnchorStyles.None;
panel.Dock = DockStyle.None;
ResumeLayout();

In my case, I edited minimum height/width of the panel and it worked.
I tried to edit the code which related to design but it was not recommended to rewrite auto-generated code.
Thank you.

Related

StartPosition CenterScreen doesn't work after resizing the Form in Form.Load

In the Form Load event I'm adding some controls to the Form dynamically.
I use this code to resize the Form to adapt its Size to the its new content:
this.MaximumSize = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
this.AutoSize = true;
this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
It works fine but StartPosition = FormStartPosition.CenterScreen doesn't work as expected:
the Form center position is calculated based on the original size.
My suggestion is to resize the Form using it's PreferredSize property. When you have added new Controls to the Form and these Controls don't fit in client area, the PreferredSize is updated to reflect the new size needed to contain them all, but limited to the Form's MaximumSize you have set.
Then use the CenterToScreen() method to center the Form to the current Screen.
CenterToParent(), suggested by Hans Passant in comments, has the same effect if the Form is not parented to any other Form: i.e., if it's not shown using the .Show(this) method overload; otherwise, it's centered to the Owner Form.
Setting AutoSizeMode = AutoSizeMode.GrowAndShrink (or calling the SetAutoSizeMode() method) and then setting AutoSize = true can have unwanted results. The more visible is that you cannot resize your Form with normal means anymore. The area occupied by a StatusStrip may not be considered etc.
As a note, if your application is not DpiAware, the Screen measures and your Form's Size may be different from what is expected. In case it's not, read about it here:
High DPI support in Windows Forms
These notes about the Screen and VirtualScreen may also be useful:
So, add your controls to the Form (maybe in the Load handler) then:
var screen = Screen.FromHandle(this.Handle);
this.MaximumSize = new Size(screen.WorkingArea.Width, screen.WorkingArea.Height);
this.ClientSize = this.PreferredSize;
this.CenterToScreen();

Sizing form to Control.Bounds.Bottom creates unexpected result

I have a windows form, in which I have a Tab Control in which I have other controls.
Since the amount of controls is dynamic and I want to size the Form just right I have this piece of code:
int w = 0;
int h = 0;
foreach (Control x in Tab_Control.Controls)
{
if (x.Bounds.Right > w) w = x.Bounds.Right;
if (x.Bounds.Bottom > h) h = x.Bounds.Bottom;
}
Tab_Control.Size = new Size(w, h);
Form1.Size = new Size(w, h);
While this sets the form width just right its height crops two controls on the bottom. I thought it might be because the positions are relative to the parent control, but when I used "PointToScreen(Point.Empty)" to get some real coordinates I found the difference to be 21 pixels, which didn't help much.
So I am wondering why setting the form height to h ends up being too short.
The discrepancy is due to the size of the form's title bar.
You are calculating the size required by the controls correctly, but you are then setting the overall size of the window - which includes the title bar - to that height.
You'll need to add on the height of the title bar to the size you are calculating.
You can get the height of the title bar from the CaptionHeight property in System.Windows.Forms.SystemInformation
If that doesn't cover all of the discrepancy then look at the form's border thickness to see if you need to take that into account as well
Simply set the ClientSize property instead.
Better yet is to write no code at all. Set the form's AutoSize property to True, AutoSizeMode to GrowAndShrink. You surely prefer setting the Margin property on control(s) at the bottom and the right so there's a decent space between the control and the border.

Combination of docking and anchoring behaviours in winforms

Today I'm trying to use c# to fit a number of windows controls onto a panel sequentially.
I would like them to dock to the top so that I can then use BringToFront() to stack them up.
HOWEVER I would also like them to be centred. Currently, docking behaviour forces the controls to the left of the screen (however much I resize and change the location property)
I then tried to anchor my controls to the top of the panel instead. This enabled the controls to be centred and also let me resize them but anchoring has no stacking behaviour and each control overwrites the previous one.
I have researched this extensively for hours and have found no answers to this question. Is it possible to use either or both of these properties to stack my controls in the centre of the panel?
My code currently stands as so:
//Docking
userControl.Dock = DockStyle.Top;
userControl.Width = 633;
userControl.Left = (pnlRules.Width - userControl.Width) / 2; //doesn't work
Point location = new Point(((pnlRules.Width - userControl.Width) / 2), 0);
userControl.Location = location; //doesn't work
userControl.BringToFront();
OR
//Anchoring
userControl.Anchor = AnchorStyles.Top;
Point location = new Point(((pnlRules.Width - userControl.Width) / 2), 0);
userControl.Location = location;
userControl.BringToFront(); //doesn't work
My outputs are either stacked controls bound to the left panel edge (docking) or overlapping controls beautifully resized and centred (anchoring)
Thanks :)
Anya
Edit:
This captions my problem quite nicely:
http://www.techrepublic.com/article/manage-winform-controls-using-the-anchor-and-dock-properties/
This explains that using docking, the controls can be stacked next to each other. I would just like the docked, stacked controls to not be bound to the left edge of the panel.
There is no way to use a combination of docking and anchoring. A TableLayoutPanel may have worked here but I was tied to a simple Panel.
The fix was to use padding to force the control to centre:
userControl.Dock = DockStyle.Top;
pnlParent.Padding = new Padding((pnlParent.Width - userControl.Width) / 2, 0, 0, 0);
userControl.BringToFront();

How to update a UserControl size which will never come in to view (only be printed)

I create a Usercontrol in code which get's a Datacontext
and than get printed but i need to refresh the Usercontrol so it get resized (Stretch to fit the Content) but i don't know how i should do this
my Code
var view = new DruckV();
view.DataContext = this;
// now i need to resize it
i tried
view.UpdateLayout();// width and height will remain by 0,0
than i can call my Printer
var printer = new Printer();
printer.Print(view);
so how should i do this because i can't use
view.Measure(UnknownSize);
view.Arrange(new Rect(new Point(0, 0), UnknownSize));
If you use 3.5 .net framework you can create a container for the control and perform Measure/Arrange for infinity size (or if control has a dynamic dimensions that depends on container size - set maximum allowed size to the container):
var panel = new StackPanel();
//panel.MaxWidth = 100; //if you control has dynamic sizing
//panel.MaxHeight = 100;
panel.Children.Add(view);
var infinitySize = double.PositiveInfinity,double.PositiveInfinity;
panel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
panel.Arrange(new Rect(0, 0, panel.DesiredSize.Width, panel.DesiredSize.Width));
view.UpdateLayout();
Unfortunately on .net 4.x this solution doesn't worked for me and only way I have found to force update controls size is create new Window with container (same as described above) and show this window outside a display screen (set Window.Left =-1000;)
BTW: in case of rendering by invisible window, size of the rendering control can't be larger than monitors screen size, and to render huge controls you have to perform ScaleTransformon it.

When I resize my Form to full screen my controls are still on old position

Here is my code
private void button1_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Normal;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Bounds = Screen.PrimaryScreen.Bounds;
pictureBox1.Dock = DockStyle.Fill;
}
What code I can applied on picturebox2 so that picturebox2 also displaced according to form ...
You can use the Dock and Anchor properties of the controls to determine their behavior when the form is resized. When using docks and anchors in WinForms, you typically decide for a primary control (group) that gets the main part of the screen and another group of controls that are aligned in the remaining area. So if you set DockStyle.Fill for PictureBox1 control, you set the other PictureBox to DockStyle.Right. When the form is resized, the main area is extended. Please note however, that it sometimes depends on the order that the controls were created on how they are aligned and whether it works as expected. It might take some experimenting with putting various controls to foreground in order to reach your goal.
This link lists a lot of tutorials on how to align controls on Windows Forms, specifically on setting anchors and docking controls.
In addition, you can use various layout controls, among them a TableLayoutPanel (Thanks #HansPassant for the hint). For a walk-through see this link.
You need to set anchors to all your controls on your form( by default all your controls are "tied" to the top and left of your form) . If anchors are not enough try using dock panels and dock your control.
You can se the anchors from the visual editor. Select a control and on the properties panel you should set the anchors.
Here you have to scale the child controls as the main window is scaled.
try the Scale method by calculating of the scale factor as below:
the code:
Size st = this.Size;
int height = st.Height;
int width = st.Width;
this.WindowState = FormWindowState.Normal;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Bounds = Screen.PrimaryScreen.Bounds;
Size newSize = this.Size;
SizeF scaleFactor = new SizeF();
scaleFactor.Height = newSize.Height / height;
scaleFactor.Width = newSize.Width / width;
this.Scale(scaleFactor);

Categories

Resources