An obvious first question when building a designer is: Where do you start? Unfortunately, the answer is that you need to start everywhere. A custom Windows Forms designer requires multiple interlocked services that all need to run correctly from the beginning. Getting this web of classes up an running is not trivial. Luckily, we have three operating samples at which to look.
I will start this part of the discussion with a comparison of the classes and interfaces implemented in the three samples. For info, I am including the namespace as well. Here are two tables of the classes and interfaces that can/are implemented in the samples. The table codes are as follows:
- DH – Interface is implemented in the DesignerHost class
- SF – Interface/class is implemented in a separate file
- NI – Interface is not implemented, but commented stubs do exist
- DEF – Uses the default implementation of the service
Here are the classes and non-service interfaces.
Classes/Interfaces | MSKB | MSDN | Dawson|
DesignerLoader | SF | | | System.ComponentModel.Design.Serialization
DesignerTransaction | SF | SF | SF | System.ComponentModel.Design
IContainer | DH | DH | DH | System.ComponentModel
IComponent | | | | System.ComponentModel
IDesigner | | | | System.ComponentModel.Design
IDesignerFilter | | | | System.ComponentModel.Design
IDesignerHost | DH | DH | DH | System.ComponentModel.Design
IDesignerLoaderHost | DH | | | System.ComponentModel.Design.Serialization
IDisposable | DH*1| DH*1| | System
IExtenderProvider | SF | | DH | System.ComponentModel
IRootDesigner | SF | | | System.ComponentModel.Design
ISite | SF*4| SF*3| SF*2 | System.ComponentModel
This table shows just the service interfaces that are/can be implemented.
Service Interfaces | MSKB | MSDN | Dawson|
IComponentChangeService | DH | DH | DH | System.ComponentModel.Design
IDesignerEventService | DH | DH | | System.ComponentModel.Design
IDesignerOptionService | | | | System.ComponentModel.Design
IDesignerLoaderService | | | | System.ComponentModel.Design.Serialization
IDesignerSerializationManager | SF | | | System.ComponentModel.Design.Serialization
IDesignerSerializationProvider | | | | System.ComponentModel.Design.Serialization
IDesignerSerializationService | | | | System.ComponentModel.Design.Serialization
IDictionaryService | SF*4| SF*3| SF*2 | System.ComponentModel.Design
IEventBindingService | SF | | | System.ComponentModel.Design
IExtenderListService | | | DH | System.ComponentModel.Design
IExtenderProviderService | DH | DH | DH | System.ComponentModel.Design
IHelpService | NI | | | System.ComponentModel.Design
IMenuCommandService | SF | SF | SF | System.ComponentModel.Design
IMenuEditorService | NI | | | System.Windows.Forms.Design
INameCreationService | DEF | SF | SF | System.ComponentModel.Design.Serialization
IPropertyValueUIService | NI | | | System.Drawing.Design
IReferenceService | NI | | | System.ComponentModel.Design
IResourceService | SF | | | System.ComponentModel.Design
ISelectionService | SF | SF | SF | System.ComponentModel.Design
IServiceContainer | DH*1| DH | DH*1 | System.ComponentModel.Design
IServiceProvider | DH*1| DH*1| SF*2 | System
IToolboxService | SF | SF | SF | System.Drawing.Design
ITypeDescriptorFilterService | SF | SF | DH | System.ComponentModel.Design
ITypeResolutionService | SF | | | System.ComponentModel.Design
IUIService | | | SF | System.Windows.Forms.Design
*1 - Omitted from the class definition
*2 – Implemented in DesignSite.cs
*3 - Implemented in SiteImpl.cs
*4 - Implemented in SampleDesignSite.cs
What does this table show? Clearly, the MSKB sample is more comprehensive than the others. Also, the samples generally implement things in the same areas of their source code. There are some exceptions. My personal preference is to separate things out as much as possible. I intend to try to do that as I create my designer.
A Site must implement IDictionaryService and it may implement other interfaces. Interfaces/classes implemented in all three samples are highlighted in red. Some interfaces which are implemented but not included in the class definition are noted.
The .NET Framework SDK definition of IDesignerHost states that an implementation should include support for IServiceContainer and IServiceProvider. We can see that all three implement IServiceContainer in their DesignerHost class. Interestingly, Divil implements IServiceProvider in a separate file. I'll eventually take a look at the how and why of that.
The list above includes more than the material implemented in the samples. This of it as a revision of my initial list. As I get my hands around forms designers, I’ll likely update the tables.