How to make location of children controls in WinForms relative? - c#

I have a custom control derived from Control which is dynamically added to the form. The control can have negative values in Location and is by default painted relative to the top left corner.
How can I get the control to have negative coordinates and painted relative to right bottom corner for example?

The question title and the question ask two different things.
For the title: yes, you can do relative placement, but you'll need to use nested layout panels, like TableLayoutPanel and FlowLayoutPanel. They should be able to do most, if not all, of what you want to do.
For the actual question:
Why?
No, you can't.

I'm not sure you can do it using Location property, w/o doing lot's of extra coding.
But (1) you can set it's "Anchor" property to Right and Bottom instead of Top and Left. Then, each time you resize the Form it will stay in the same spot relative to Right-Bottom corner of containing panel (the Form). Then (2) can set your Top-Left of Location to such values that it will be out of visible area... so Every time your Form (or Panel) is resized - Control will stay out of visible area.
Hopes it help.

You could do something like
Point relativePos = new Point(-10, -10);
control.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
control.Location = new Point(this.ClientSize.Width - control.Width + relativePos.X, this.ClientSize.Height - control.Height + relativePos.Y);
where relative pos is the position relative to the bottom right. The anchor makes sure it stays there on resize.

I made small class to manage position and size depends on container size :
http://www.codeproject.com/Tips/492814/Relative-design-components-on-WinForm

Related

Resize in Windows Forms controls along with form resize

I have a few controls (group boxes, tables, gridview, etc.) in my C# Windows Forms application, and I would like to scale them based on screen width/height.
For example, the screen starts at, let's say, 640x480 and then it gets maximized to 1920x1200.
I want to be able to increase the width/height of the controls so they look the exact same after the window gets re-sized.
What is the best way to do that, without setting every width/height property manually?
What is the best way to do that, without setting every width/height property manually?
Instead of specifying width and height, you can use the Anchor and Dock properties to have controls scale based on their containing elements.
Alternatively, you can use TableLayoutPanel or FlowLayoutPanel to arrange your controls.
I believe you want the control's Anchor property.
As the name implies, this property forces the control to anchor itself
in a relative or absolute position within the parent form or control.
This property has four values that can be turned on or off:
Top -- Indicates that the control should keep its top edge stationary in respect to the parent form (or control) top edge.
Bottom -- Indicates that the control should keep its bottom edge stationary in respect to the parent form (or control) bottom edge.
Left -- Indicates that the control should keep its left edge stationary in respect to the parent form (or control) left edge.
Right -- Indicates that the control should keep its right edge stationary in respect to the parent form (or control) right edge.
IIRC, you want to select all the controls on the form using Ctrl+A, and then setting the anchor property to top, bottom, left, and right.

How to dock a child control to bottom right of the parent control?

How do i dock a child control at a bottom right position when compared to the parent control?
I can see that the dockstyle enum has values for
None,Top,Bottom,Right,Left and Fill ...
How can i set for Bottom right ???
perhaps you don't want to dock it bottom-right. Docking changes the position of the control, but also the size to fit in th height or width of the form.
If you want to keep it down and on the right, anchor it.Remove left and top anchors and add bottom and right anchors. Your control will keep there!
** EDIT **
According to OP comment, it must be on the bottom and take all width and have fixed height. then you must take this steps:
To keep it tidy, you need at least 2 controls:
The one that it's on the bottom: dock it to the bottom and set its height.
Other one that use docking style of Fill. This makes it take all the space not occupied by the bottom control.
If you have problems setting it up, use the Layout Window (I hope that's the name in English. My VS is localized) to move them around until it works. Sometimes docking it's a bit nasty and the only way to make it work the way you like is changing the order nad nesting of controls using this layout window.
Use AnchorStyles:
yourComponent.Anchor = ((System.Windows.Forms.AnchorStyles)
((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
To "dock" in the bottom right, you need to
Dock ControlA on the Right side of the parent, ControlB
Set the Top Padding of ControlA to ControlA.Padding = new Padding(0, ControlB.Height - nTopPadding, 0, 0);
nTopPadding can be whatever you need it to be. For TextBoxes, Labels, and the like, ControlA.Font.Height works the best.
This also works when AutoSize = true. You'll only need to update the padding as needed.
From MSDN documentation for Control.Dock:
A control can be docked to one edge of its parent container or can be
docked to all edges and fill the parent container.
So you cannot dock to two edges - I'm actually not sure what you mean by this.
If you want to keep a control in the bottom right of the screen you might be thinking of the Anchor property, which does let you set multiple edges to anchor the control to.
try setting the Dock to Bottom, Depending on your control you may have to turn autosize off, a label for instance

Center buttons in a container

How does one specify that a button centers itself in a container without having to specify a Location? Is it even possible?
The goal is to be able to center multiple buttons in a panel without having to perform calculations on their placement.
I know it is possible to center some controls on a form, not sure about a panel though. Anyway:
Disable the Left and Right anchors of your control if you want your controls to stay centered horizontally, and the Top and Bottom anchors if you want your controls to stay centered vertically,
In the designer window, select your control,
In the VS 'Format' menu, hit 'Center in form', then 'Horizontally' and/or 'Vertically'.
If you want to center several controls side to side, select them all and execute the above steps.
Controls will then stay centered in the form when the user resizes the window.
I'm not 100% sure of what you are asking, but try using a TableLayoutPanel, and drop one button in each cell of the table. If you anchor the TableLayoutPanel to the Top, Left, Bottom& Right, the Table will grow and shrink with the form, but each button will "float" relative to the top-left corner of it's containing cell.
Disabling all anchoring will keep the TableLayoutPanel at it's relative location within your form, but your buttons will remain spaced out evenly amongst one another.
Between standard control anchoring and/or the the TableLayoutPanel you should be able to find the correct type of anchoring that you desire.

SplitContainer - What causes the inconsistent behaviour I experience when the orientation is set to horizontal?

Starting from scratch in a new project in which the properties of the default Form1 form have not been altered I drop a SplitContainer on the form and set its properties to:
Anchor - Top, Left
Dock - Fill
Orientation - Vertical
I then drop a second SplitContainer into the left-hand panel (panel 1) of the first SplitContainer and again set its properties to those above except this time the orientation of the splitter is set to horizontal.
I now place two CheckedListBoxes in both the upper and lower panels (panels 1 & 2) of the second SplitContainer. The properties of both CheckedListBoxes are set to:
Anchor - Top, Left
Dock - Fill
I now add a TextBox to the right-hand panel (panel 2) of the first SplitContainer and set its properties to:
Anchor - Top, Left
Dock - Fill
Multi-Line - True
When I compile and run this application the vertical splitter which forms part of the first SplitContainer I added behaves and works exactly as expected - so no problem there.
However, the horizontally oriented splitter in the second SplitContainer consistently displays erratic behaviour - the width of the splitter itself changes as it is moved up and down. But this increase or decrease in the width of the splitter is also not consistent with the direction in which it was moved - for example moving it up some distance from its initial position at startup may result in the splitter being thinner than what it was previously while a further resizing upwards results in it being thicker.
The bottom edge of the lower CheckedListBox also moves up and down when I move the splitter and as before this behaviour is not consistent with the direction in which the splitter is moved.
To avoid carrying over changes to a component's properties from one experiment to another I have been trying to figure out what is going on by starting half a dozen or so new projects from scratch and trying out different things including changes to the Anchor, BorderStyle, Dock, and Margin properties, but unfortunately I am none the wiser : -(
Has anyone had similar experience of this erratic behaviour and can offer me a solution? I might be overlooking something simple, if so what is it?
Thanks for reading.
Edit \ Update -
Upon further experimentation I was able to determine that the unwanted behaviour I am experiencing is related somehow to the CheckedListBoxes - I replaced both with multi-line textboxes whose properties of "Anchor" and "Dock" were set to "Top, Left" and "Fill" respectively and upon running the app the erratic behaviour no longer occurs - both the vertical and horizontal splitters are working correctly.
Set the IntegralHeight property of the list boxes to False so that they are allowed to size themselves to fit the panel.

Using anchor property with dynamically added controls

I'm adding some textboxes to a form dynamically at runtime. Everything works fine i.e. the textboxes are aligned, anchored and automatically resizes until the form is maximized. On maximizing the form, the textboxes are added to the same location while the form was not maximized. This causes a misalignment of the textboxes.
How can I ensure that all the textboxes are at the same location and of the same size both while the windowstate is normal as well as maximized?
EDIT:
Btw I'm using C#
EDIT:
Would a flowlayoutpanel be useful here?
It's a quite old question, but maybe i'm able to answer it.
After reading all your comments, i think i can summarize your problem to this:
You have a form at a specific size and add some controls at runtime at a specific location with anchor set to Top | Right.
If you just display the form and let the controls appear everything works fine
If you maximize your form (or change the size of it) your controls won't be appear anymore at the correct location you want.
To get rid of this problem you can try some different approaches:
Use a FlowLayoutPanel, take care for the FlowDirection and maybe just create all your needed controls beforehand and just toggle the visible state.
Use correct values for the location of your newly created controls.
The second point is the error you have (i think). You found someway to calculate the location of your control if your form has it's original size. To get the correct position if the size of the form has changed (e.g. maximized) you have to consider several factors.
The delta values from your default size to your current size.
The Anchor(s) you wish to set on your control.
In your case you'd like to put a control which is anchored Top | Right, but the location is set by Top | Left. In that case you have to calculate the difference between the control.location.x and the form.width in it's default size. Then you take this difference and subtract it from the form current width. Now you can place your control at this position (cause Top never changes through a resizing). If you have a Anchor at Bottom | Right you have to calculate the same with control.location.y and form.height.
The behaviour and calculation if no anchor, for Top | Bottom or Left | Right are set is left as an exercise to the reader. ;-)
Last but not least there is also another hacky way to get your control at the right position:
If you like to place a new control somewhere change the Form.Visible to false
Save the form state, size and location
Change them to your default values
Add the controls you want
Restore the formerly saved values
Make the form visible again.
The Anchor property specifies which borders the controls should ensure they're always the same distance from. It can get pretty confusing, which is why you're seeing things shift around when anchored to the right border.
If you just want to ensure that the textbox display stays consistent relative to itself, I'd suggest putting down a Panel, with anchoring on the Panel, and then adding textboxes to the Panel. The X and Y coordinates on your text boxes become relative to the Panel, so it's a lot easier to do layout especially when the location of the Panel suddenly changes.

Categories

Resources