Marco Regueira
Marco Regueira

Reputation: 1088

Automate control creation in windows forms designer

I need to automate creation and configuration of several controls in the form while in design mode.

For things like that, I create a control that interacts and modifies some other controls in the form and sets default values, adds columns to grids,... Once done, I remove the control and that's it.

This is a not quite elaborate technique to create ad-hoc macros, but it works like a charm to ease repetitive work configuring properties, specially with "big" objects with a lot of elements like grids.

The problem is that I'm not able to create new controls and add them to the form dynamically while in design mode. Consider the following code (just a simplified example):

  public partial class ButtonCreator : UserControl

    [Category("Automation")]
    public int LeftPosition { get; set; }

    [Category("Automation")]
    public bool AutoCreate
    {
        get { return false; }
        set
        {
            var form = FindForm();

            if (value)
            {
                for (var i = 10; i < 100; i = i + 20)
                {
                    var button = new Button(){Name = "btn_" + DateTime.Now.Ticks + "_" + i};
                    form.Controls.Add(button);
                    button.Location = new Point(LeftPosition, i);
                    button.BringToFront();
                }
            }
        }
    }

(I've also tried using a component designer with a similar code, but with the same result, so this way is much less verbose)

To use this I add an instance of ButtonCreator to the Form, then I set the AutoCreate property (while in design mode, from the property list). Apparently It works and adds the buttons to the form, but they are not serialized to the autogenerated C# code and I lose them after saving.

Is there something I can do to force them to serialize when Visual studio generates the designer.cs file?

Consider this restriction: This is not code to be released, just dirty code to ease development, therefore I prefer to avoid more complex techniques to be able to introduce changes easily, right while coding. References to Visual Studio automation, or creating visual studio extensions should be avoided if possible.

Upvotes: 1

Views: 484

Answers (1)

Marco Regueira
Marco Regueira

Reputation: 1088

According to comment by Hans Passant, all that is needed is to ask the designer environment to create the object, so the new component can be tracked.

   var host = GetService(typeof(IDesignerHost)) as IDesignerHost;
   var button = host.CreateComponent(typeof(Button), "someName") as Button;
   FindForm().Controls.Add(button);

Upvotes: 2

Related Questions