C4u C4u - 3 months ago 30
C# Question

Container UserControl - Handle and Modify Added Controls

I'm trying to create a custom container as

UserControl
.

My Goal: I want to be able to drag controls inside the designer and handle incoming controls inside the code of my usercontrol.

Example: I place my container somewhere and then add a button. In this momemt I want my usercontrol to automatically adjust the width and position of this button. Thats the point where Im stuck.

My code:

[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class ContactList : UserControl
{
public ContactList()
{
InitializeComponent();
}

private void ContactList_ControlAdded(object sender, ControlEventArgs e)
{
e.Control.Width = 200; // Nothing happens
e.Control.Height = 100; // Nothing happens

MessageBox.Show("Test"); // Firing when adding a control
}
}


enter image description here

enter image description here

The
MessageBox
is working well. The set
width
and
height
is ignored.

The question is just "why?".




EDIT

I've just noticed, when placing the button and recompiling with F6 the button gets resized to 200x100. Why isnt this working when placing?

I mean... the
FlowLayoutPanel
handles added controls right when you place it. Thats the exact behaviour im looking for.

enter image description here

Answer

Using OnControlAdded

To fix your code, when you drop a control on container and you want to set some properties in OnControlAdded you should set properties using BeginInvoke, this way the size of control will change but the size handles don't update. Then to update the designer, you should notify the designer about changing size of the control, using IComponentChangeService.OnComponentChanged.

Following code executes only when you add a control to the container. After that, it respects to the size which you set for the control using size grab handles. It's suitable for initialization at design-time.

protected override void OnControlAdded(ControlEventArgs e)
{
    base.OnControlAdded(e);
    if (this.IsHandleCreated)
    {
        base.BeginInvoke(new Action(() =>
        {
            e.Control.Size = new Size(100, 100);
            var svc = this.GetService(typeof(IComponentChangeService)) 
                          as IComponentChangeService;
            if (svc != null)
                svc.OnComponentChanged(e.Control, 
                   TypeDescriptor.GetProperties(e.Control)["Size"], null, null);
        }));
    }
}
Comments