mfc
mfc

Reputation: 11

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.

Upvotes: 0

Views: 1764

Answers (2)

mfc
mfc

Reputation: 11

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++;
    }
}

Upvotes: 1

Mauro Sampietro
Mauro Sampietro

Reputation: 2814

Let's say you want your inner element always distant from the left border 1% of the total window width. You can calculate your actual value after the initialization of your form.

While resizing (there's an event) recalculate the concrete left position by calculating the new distance and assigning it Left = form.Width*0.01

Upvotes: 0

Related Questions