mfc mfc - 3 months ago 19
C# Question

C# Windows Forms How to keep control's location and size relatively constant to its parent container?

How I need it:

left to right

Dock:

I don't want to dock it to any of sides basically.

Anchor to all sides:

keeps the corner location constant

Anchor None:

It does keeps the locations relatively constant but doesn't resize them at all.

And I am out of options apart from modifying the Resize event of the container Control and iterate through all its children I believe.

Please show me a cleaner way, thanks.

Edit:
I will have multiple controls floating in this container. So,

TableLayoutView
is not an option for this case.

Also, in answer from sam he suggests to manually do the job like I was afraid of. Well, I guess I will have to do it like that.

Which is manually iterating through the children controls on the
Resize
event of the container control.

I will mark this as solved although I am not satisfied.

mfc mfc
Answer

Final Result:

Resizing done.

I have this class which holds references to the container and its children. Foreign DynoPanel here holds a control inside it.

private readonly Dictionary<string, DynoPanel> children;
public Panel container;
private List<Rectangle> startingRectangles;

public DynoContainer(Control parent)
{
    children = new Dictionary<string, DynoPanel>();
    container = new Panel
    {
        Dock = DockStyle.Fill
    };
    parent.Controls.Add(container);
    container.FindForm().ResizeBegin += OnResizeBegin;
    container.Resize += ContainerOnResize;
}

Here we store the Starting locations and sizes of container and its children on the ResizeBegin event of the mother form:

private void OnResizeBegin(object sender, EventArgs eventArgs)
{
    startingRectangles = new List<Rectangle>();
    startingRectangles.Add(container.Bounds);
    foreach (var dynoPanel in children)
        startingRectangles.Add(dynoPanel.Value.self.Bounds);
}

Then according to the new scale factor we calculated, children's locations and sizes are set, conserving the initial ratio on actual Resize event:

private void ContainerOnResize(object sender, EventArgs eventArgs)
{
    var scale = new PointF(
        (float) container.Width/startingRectangles[0].Width,
        (float) container.Height/startingRectangles[0].Height);
    int index = 1;
    foreach (var panel in children)
    {
        panel.Value.self.Location = new Point(
            (int) (startingRectangles[index].X*scale.X),
            (int) (startingRectangles[index].Y*scale.Y)
            );
        panel.Value.self.Size = new Size(
            (int) (startingRectangles[index].Width*scale.X),
            (int) (startingRectangles[index].Height*scale.Y)
            );
        index++;
    }
}