Hosting Windows Forms Designers

Making it Work

That's about it for the DesignerHost and its related classes. The way we've written it, all it needs to be instantiated is a ServiceContainer instance. The framework provides a simple implementation of this, so we'll just use that. We want a very simple design surface so we'll just make a form with one side reserved for a propertygrid.

Now, how do we actually put our DesignerHost to use? It comes back to the Root Designer we discussed earlier. The key method is has is GetView, which returns a Control that can be added to any other form or control. This control is what you see when you look at a form in design view; it has a white background, and shows the form in design mode sitting in the top left.

Once we have created our DesignerHost, we (the host application) needs to subscribe to the SelectionChanged event of the ISelectionService interface that we already implemented. This is so that we can display the properties of the selected objects in our propertygrid.

We will use the following code to instantiate a form, put it in to design mode by adding it to our host, get its design view and add that view to the form:

private void Initialize()
{
    IDesignerHost host;
    Form form;
    IRootDesigner rootDesigner;
    Control view;
    // Initialise service container and designer host
    serviceContainer = new ServiceContainer();
    serviceContainer.AddService(typeof(INameCreationService),
    new NameCreationService());
    serviceContainer.AddService(typeof(IUIService), new UIService(this));
    host = new DesignerHost(serviceContainer);
    // Add toolbox service
    serviceContainer.AddService(typeof(IToolboxService), lstToolbox);
    lstToolbox.designPanel = pnlViewHost;
    PopulateToolbox(lstToolbox);
    // Add menu command service
    menuService = new MenuCommandService();
    serviceContainer.AddService(typeof(IMenuCommandService), menuService);
    // Start the designer host off with a Form to design
    form = (Form)host.CreateComponent(typeof(Form));
    form.TopLevel = false;
    form.Text = "Form1";
    // Get the root designer for the form and add its design view to this form
    rootDesigner = (IRootDesigner)host.GetDesigner(form);
    view = (Control)rootDesigner.GetView(ViewTechnology.WindowsForms);
    view.Dock = DockStyle.Fill;
    pnlViewHost.Controls.Add(view);
    // Subscribe to the selectionchanged event and activate the designer
    ISelectionService s = (ISelectionService)serviceContainer.GetService(
    typeof(ISelectionService));
    s.SelectionChanged += new EventHandler(OnSelectionChanged);
    host.Activate();
}

Conclusion

Reading over the code should fill in any gaps that I missed out while writing this. Hopefully this article will encourage more people to make use of the designer architecture in their own applications.

I have provided an example project that covers everything in this article (just click the download link above). Thanks to Ken Swinney for the VB version.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“My definition of an expert in any field is a person who knows enough about what's really going on to be scared.” - P. J. Plauger