<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Forms Designer</title>
        <link>http://geekswithblogs.net/mtreadwell/category/7229.aspx</link>
        <description>Programming thread about creating a .NET custom forms designer</description>
        <language>en-US</language>
        <copyright>Mark Treadwell</copyright>
        <managingEditor>eep@narboza.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Custom Forms Designer: Toolbox and ToolboxService - Part 1</title>
            <link>http://geekswithblogs.net/mtreadwell/archive/2007/10/25/116359.aspx</link>
            <description>&lt;p&gt;Reminder: All posts in this series can be found &lt;a href="http://geekswithblogs.net/mtreadwell/category/7229.aspx"&gt;here&lt;/a&gt;.  &lt;/p&gt;&lt;p&gt;The Toolbox and the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.designsurface(VS.80).aspx" target="_blank"&gt;DesignSurface&lt;/a&gt; work together to allow a developer to add new components and controls to the design surface.  There are two interfaces that implement this functionality: &lt;a href="http://msdn2.microsoft.com/en-us/library/system.drawing.design.itoolboxservice(vs.80).aspx" target="_blank"&gt;IToolboxService&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/system.drawing.design.itoolboxuser(VS.80).aspx" target="_blank"&gt;IToolboxUser&lt;/a&gt;.  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;IToolboxService&lt;/strong&gt; defines an interface that provides methods and properties to manage and query the Toolbox capabilities in a development environment.  All forms designer systems must implement the IToolboxService in their Toolbox in order to provide the expected Windows Forms UI functionality.  This service is added to the &lt;a href="http://geekswithblogs.net/mtreadwell/archive/2007/10/22/116248.aspx" target="_blank"&gt;ServiceContainer&lt;/a&gt; and can be accessed at any time. There are 15 methods and two properties in the interface which I will not cover here in detail.  Many of those methods deal with adding, deleting and selecting Toolbox items.  &lt;/p&gt;&lt;p&gt;&lt;strong&gt;IToolboxUser&lt;/strong&gt; defines an interface for setting the currently selected toolbox item and indicating whether a designer supports a particular toolbox item.  A forms designer will implement an IToolboxUser interface that consists of only two methods: GetToolSupported and ToolPicked.  You use GetToolSupported to filter the items that can be added onto the designer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;:  There are several steps you have to take to build a Toolbox for a Forms Designer system.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Create a user interface that displays the tools to the user.  This is typically implemented as a classic &lt;a href="http://msdn.microsoft.com/msdnmag/issues/04/12/CustomFormsDesigner/" target="_blank"&gt;TreeView&lt;/a&gt;, or as &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/03/DesignerHosting/" target="_blank"&gt;sliding tree control&lt;/a&gt; that behaves much like Windows Explorer, but without grid or connection lines.  Building the desired functionality can take quite a bit of time.  There is a nice Code Project &lt;a href="http://www.codeproject.com/cs/miscctrl/IPToolbox.asp" target="_blank"&gt;article&lt;/a&gt; that has a mostly-complete solution with multi-level tabs.  There are several design decisions you will have to make before you start coding.  Besides the visual representation already noted, you must decide how you will discover, categorize, and load the tools.  One of the &lt;a title="Microsoft Developer Network" href="http://msdn.microsoft.com/" target="_blank"&gt;MSDN&lt;/a&gt; Magazine &lt;a href="http://msdn.microsoft.com/msdnmag/issues/04/12/CustomFormsDesigner/#S3" target="_blank"&gt;articles&lt;/a&gt; describes three methods: hard coding (not recommended), configuration file, and attribute decorated classes loaded from a known location and checked using reflection. &lt;/li&gt;&lt;li&gt;Implement the IToolboxService.  The three main members of this interface are GetSelectedToolboxItem, SerializeToolboxItem, and DeserializeToolboxItem.  Other useful members include GetCursor, IsSupported, IsToolboxItem, and SelectedToolboxItemUsed. &lt;/li&gt;&lt;li&gt;Plug the IToolboxService implementation into the design-time environment. &lt;/li&gt;&lt;li&gt;Create a keyboard interface. &lt;/li&gt;&lt;li&gt;Handle Toolbox events, such as tool selection, keyboard, mouse clicks and drag and drop.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;: There are four ways a developer can add a component or control to a forms designer DesignSurface; one uses the keyboard, while the other three use the mouse.  The Visual Studio Toolbox functions are described &lt;a href="http://msdn2.microsoft.com/en-us/library/ms165354(vs.80).aspx" target="_blank"&gt;here&lt;/a&gt;.  I will talk about the changes required to the sample application to implement the Visual Studio functionality in Part 2 of this post.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;u&gt;Keyboard&lt;/u&gt;:  The Visual Studio Toolbox keyboard interface is described &lt;a href="http://msdn2.microsoft.com/en-us/library/k8hcfy22(VS.80).aspx" target="_blank"&gt;here&lt;/a&gt;.  Essentially, you Ctrl+Tab/cursor to the Toolbox (or press Ctrl+Alt+X), cursor to the desired control and hit Enter. The control will be added to the DesignSurface.  Ctrl+Up Arrow, Ctrl+Down Arrow, Left Arrow, and Right Arrow also have control functions within the Toolbox.  &lt;/li&gt;&lt;li&gt;&lt;u&gt;Mouse&lt;/u&gt;: Double-Click a Toolbox icon.  The control will be added to the DesignSurface.  This has the same effect as using the keyboard method.  &lt;/li&gt;&lt;li&gt;&lt;u&gt;Mouse&lt;/u&gt;: Single Click a Toolbox icon.  Move the cursor over the DesignSurface, were it will turn to a Crosshair ready for you to click and drag the desired control location and size.  Visual Studio customizes the Crosshair cursor with color overlay of the selected tool icon until the mouse has been clicked and released.  This operation can be canceled with the Esc key. &lt;/li&gt;&lt;li&gt;&lt;u&gt;Mouse&lt;/u&gt;: Drag and Drop a Toolbox icon.  Click a control icon, drag it onto the DesignSurface, and drop it where you want it.  This operation can be canceled with the Esc key.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;To allow the icons from the Toolbox to be added to the DesignSurface using the mouse or keyboard, the Toolbox in the sample code hooks onto the KeyDown and MouseDown events.  IToolboxUser.ToolPicked is called for the Enter key or a mouse double-click.  The sample code shows how to serialize the ToolboxItem into a DataObject and to DoDragDrop for when a mouse single-click event occurs.  IToolboxService.SerializeToolboxItem will be called on mouse up and the item will be added to the designer.  &lt;/p&gt;&lt;p&gt;When a new control or component is added to the DesignSurface from the Toolbox, the NameCreationService is used to give it a unique name.  My discussion of this service and my modifications to the sample code are described &lt;a href="http://geekswithblogs.net/mtreadwell/archive/2007/10/18/116143.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116359"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116359" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/mtreadwell/aggbug/116359.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mark Treadwell</dc:creator>
            <guid>http://geekswithblogs.net/mtreadwell/archive/2007/10/25/116359.aspx</guid>
            <pubDate>Fri, 26 Oct 2007 04:41:24 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/mtreadwell/comments/116359.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/mtreadwell/archive/2007/10/25/116359.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/mtreadwell/comments/commentRss/116359.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/mtreadwell/services/trackbacks/116359.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom Forms Designer: ServiceContainer</title>
            <link>http://geekswithblogs.net/mtreadwell/archive/2007/10/22/116248.aspx</link>
            <description>&lt;p&gt;Reminder: All posts in this series can be found &lt;a title="Custom Forms Designer Series" href="http://geekswithblogs.net/mtreadwell/category/7229.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Simply, it is a container for services.  Services are classes that have a well-known interface, that have instantiations which be stored in service containers, can be obtained from a service provider, and are addressable by type.  The ServiceContainer class is a service provider and implements IServiceProvider.  You obtain a service by supplying the Type of the service you want to the service provider's GetService method.  The ServiceContainer.GetService method is declared like this.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font size="2"&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;virtual&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Object&lt;/span&gt; GetService(&lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt; serviceType);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; &lt;p&gt;This is how you obtain a a reference to a service in a class derived from DesignSurfaceManager or DesignSurface.  The cast is required because GetService returns an Object.&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: rgb(43,145,175)"&gt;INameCreationService&lt;/span&gt; serviceNameCreation &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;INameCreationService&lt;/span&gt;)(&lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetService(&lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;INameCreationService&lt;/span&gt;)));&lt;/font&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Both DesignSurfaceManager and DesignSurface implement ServiceContainer.  This may appear to lead to confusion, but you do not have to keep track of which container holds what service.  One of the nice features of using the DesignSurfaceManager class is that it automatically merges services between it and the DesignSurfaces.&lt;/p&gt;
&lt;p&gt;There is no documentation of how to use these multiple implementations, but it makes sense to put general, non-DesignSurface services such as IHelpService, IDesignerEventService, and INameCreationService in the central DesignSurfaceManager ServiceContainer.  DesignSurface-specific services such as ISelectionService would logically be with each DesignSurface.ServiceContainer.&lt;/p&gt;
&lt;p&gt;MSDN states the following about the DesignSurfaceManager.ServiceContainer Property: The DesignSurfaceManager class provides several design-time services automatically.  You can override each of these services by replacing them in the protected &lt;font color="#000000"&gt;&lt;span style="color: rgb(0,0,255)"&gt;&lt;font color="#000000"&gt;ServiceContainer property.  To replace a service, override the constructor, call base, and make any changes through the protected ServiceContainer property.  All services added to the service container that implement the &lt;/font&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&lt;font color="#000000"&gt;IDisposable interface are disposed when the design surface manager is disposed.  The DesignSurfaceManager class provides the&lt;/font&gt; &lt;/span&gt;&lt;/font&gt;&lt;span style="color: rgb(0,0,255)"&gt;&lt;font color="#000000"&gt;IDesignerEventService interface as the default service.  IDesignerEventService provides a global eventing mechanism for designer events.  With this mechanism, an application is informed when a designer becomes active.  The service provides a collection of designers and a single place where global objects, such as the Properties window, can monitor selection change events.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;What is interesting here is that MSDN itself does not state what the default design-time services are.  A MSDN Magazine designer hosting &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/03/DesignerHosting/"&gt;article&lt;/a&gt; provides a &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/03/DesignerHosting/default.aspx?loc=&amp;amp;fig=true#fig4" target="_blank"&gt;table&lt;/a&gt; of the default DesignSurface design-time services.  An important part of that table is listing which services are not replaceable due to their interrelationships.  I wrote some code to see what services were running in the two containers for the sample application and found the following.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font size="2"&gt;HostSurfaceManager.ServiceContainer Services&lt;br /&gt;--------------------------------------------&lt;br /&gt;IDesignerEventService&lt;br /&gt;INameCreationService&lt;br /&gt;IToolboxService&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;HostSurface.ServiceContainer Services&lt;br /&gt;--------------------------------------------&lt;br /&gt;IComponentChangeService&lt;br /&gt;IDesignerEventService&lt;br /&gt;IDesignerHost&lt;br /&gt;IExtenderListService&lt;br /&gt;IExtenderProviderService&lt;br /&gt;IInheritanceService&lt;br /&gt;IMenuCommandService&lt;br /&gt;INameCreationService&lt;br /&gt;IReferenceService&lt;br /&gt;ISelectionService&lt;br /&gt;IToolboxService&lt;br /&gt;ITypeDescriptorFilterService&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This list matches almost perfectly with the default design-time service table noted above.  It was not surprising to see the three HostSurfaceManager services were also visible from the HostSurface because the System.ComponentModel.Design.DesignSurfaceManager has a small bit of code in its MergedServiceProvider GetService method that looks like the following: &lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;font size="2"&gt;&lt;span style="color: rgb(43,145,175)"&gt;Object&lt;/span&gt; service &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;_primaryProvider&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetService(serviceType);
&lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (service &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
{
  service &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;_secondaryProvider&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetService(serviceType);
}&lt;br /&gt;&lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; service;&lt;/font&gt;&lt;/pre&gt;&lt;/blockquote&gt;The primary provider for the HostSurface is its own ServiceContainer.  The secondary provider for the HostSurface is the HostSurfaceManager.ServiceContainer.  As shown in the code snippet, any HostSurface service is preferred over an identical one in the HostSurfaceManager.  Any service unavailable in the HostSurface but present in the HostSurfaceManager is accessible as well.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116248"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116248" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/mtreadwell/aggbug/116248.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mark Treadwell</dc:creator>
            <guid>http://geekswithblogs.net/mtreadwell/archive/2007/10/22/116248.aspx</guid>
            <pubDate>Tue, 23 Oct 2007 03:15:32 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/mtreadwell/comments/116248.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/mtreadwell/archive/2007/10/22/116248.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/mtreadwell/comments/commentRss/116248.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/mtreadwell/services/trackbacks/116248.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom Forms Designer: Name Creation Service</title>
            <link>http://geekswithblogs.net/mtreadwell/archive/2007/10/18/116143.aspx</link>
            <description>&lt;p&gt;Reminder: All posts in this series can be found &lt;a title="Custom Forms Designer Series" href="http://geekswithblogs.net/mtreadwell/category/7229.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The first code I will look at is from one of the simplest services supporting the Windows Forms designer.  The Name Creation Service is called each time you drop a control/component onto the visual design surface.  Your job is to return a unique name for the new control that also means something.&lt;/p&gt; &lt;p&gt;The standard process, &lt;a href="http://blogs.msdn.com/brada/pages/361363.aspx"&gt;per convention&lt;/a&gt;, is to take the control/component Type name, camel case it (lower case the first letter) since it will be a member variable, and then append a digit suffix to make it unique from all other controls/components on the form.  The number ensures it remains &lt;a href="http://msdn2.microsoft.com/en-us/library/x2dbyw72(VS.71).aspx"&gt;unique&lt;/a&gt; for languages which are not case sensitive.&lt;/p&gt; &lt;p&gt;The &lt;a href="http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/DesignerHosting.exe"&gt;sample code&lt;/a&gt; implements only the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice.createname.aspx"&gt;INameCreationService.CreateName&lt;/a&gt; method.  I modeled my implementation off of the sample code for &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice_members.aspx"&gt;INameCreationService&lt;/a&gt; &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice.aspx"&gt;here&lt;/a&gt;.  I found the sample &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice.createname.aspx"&gt;CreateName&lt;/a&gt; code to be excessively complex:&lt;/p&gt;&lt;pre class="code"&gt;&lt;font size="1"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;INameCreationService&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;CreateName(&lt;span style="color: rgb(43,145,175)"&gt;IContainer&lt;/span&gt; container, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt; type)
    {
      &lt;span style="color: rgb(43,145,175)"&gt;ComponentCollection&lt;/span&gt; cc &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; container&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Components;
      &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; min &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Int32&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;MaxValue;
      &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; max &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Int32&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;MinValue;
      &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; count &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;0&lt;/span&gt;;
      &lt;span style="color: rgb(0,0,255)"&gt;for&lt;/span&gt; (&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; i &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;0&lt;/span&gt;; i &lt;span style="color: rgb(128,128,0)"&gt;&amp;lt;&lt;/span&gt; cc&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Count; i&lt;span style="color: rgb(128,128,0)"&gt;++&lt;/span&gt;)
      {
        &lt;span style="color: rgb(43,145,175)"&gt;Component&lt;/span&gt; comp &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; cc[i] &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Component&lt;/span&gt;;
        &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (comp&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetType() &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; type)
        {
          count&lt;span style="color: rgb(128,128,0)"&gt;++&lt;/span&gt;;
          &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; name &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; comp&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Site&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name;
          &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (name&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;StartsWith(type&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name))
          {
            &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;            {
              &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; value &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Int32&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Parse(name&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Substring(type&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Length));
              &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (value &lt;span style="color: rgb(128,128,0)"&gt;&amp;lt;&lt;/span&gt; min)
                min &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; value;
              &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (value &lt;span style="color: rgb(128,128,0)"&gt;&amp;gt;&lt;/span&gt; max)
                max &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; value;
            }
            &lt;span style="color: rgb(0,0,255)"&gt;catch&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt; ex)
            {
              Trace&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;WriteLine(ex&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;ToString());
            }
          }
        }
      }&lt;/font&gt;&lt;span style="color: rgb(0,128,0)"&gt;
&lt;/span&gt;&lt;font size="1"&gt;      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (count &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;0&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; type&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name &lt;span style="color: rgb(128,128,0)"&gt;+&lt;/span&gt; &lt;span style="color: rgb(163,21,21)"&gt;"1"&lt;/span&gt;;
      &lt;span style="color: rgb(0,0,255)"&gt;else&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (min &lt;span style="color: rgb(128,128,0)"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;1&lt;/span&gt;)
      {
        &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; j &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; min &lt;span style="color: rgb(128,128,0)"&gt;-&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;1&lt;/span&gt;;
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; type&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name &lt;span style="color: rgb(128,128,0)"&gt;+&lt;/span&gt; j&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;ToString();
      }
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,0,255)"&gt;else
&lt;/span&gt;      {
        &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; j &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; max &lt;span style="color: rgb(128,128,0)"&gt;+&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;1&lt;/span&gt;;
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; type&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name &lt;span style="color: rgb(128,128,0)"&gt;+&lt;/span&gt; j&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;ToString();
      }
    }&lt;/font&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;My implementation is simpler:&lt;/p&gt;&lt;pre class="code"&gt;&lt;font size="1"&gt;    &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;INameCreationService&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;CreateName(&lt;span style="color: rgb(43,145,175)"&gt;IContainer&lt;/span&gt; container, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt; dataType)
    {
      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (dataType &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
      {
        &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"dataType"&lt;/span&gt;);
      }
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// The base component name is the Type name with the first character lower case
&lt;/span&gt;      &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; name &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Char&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;ToLower(dataType&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name[&lt;span style="color: rgb(255,0,255)"&gt;0&lt;/span&gt;]) &lt;span style="color: rgb(128,128,0)"&gt;+&lt;/span&gt; dataType&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Name&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Substring(&lt;span style="color: rgb(255,0,255)"&gt;1&lt;/span&gt;);
      &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; number &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;1&lt;/span&gt;;
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// If the container parameter is null, no container search is needed
&lt;/span&gt;      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (container &lt;span style="color: rgb(128,128,0)"&gt;!=&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
      {
        &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Increment counter until we find a name that is not in use
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;while&lt;/span&gt; (container&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Components[name &lt;span style="color: rgb(128,128,0)"&gt;+&lt;/span&gt; number&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;ToString()] &lt;span style="color: rgb(128,128,0)"&gt;!=&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
        {
          &lt;span style="color: rgb(128,128,0)"&gt;++&lt;/span&gt;number;
        }
      }
      &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; (name &lt;span style="color: rgb(128,128,0)"&gt;+&lt;/span&gt; number&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;ToString());
    }
&lt;/font&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;I also added implementations of &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice.isvalidname.aspx"&gt;INameCreationService.IsValidName&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice.validatename.aspx"&gt;INameCreationService.ValidateName&lt;/a&gt;.  The &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice.isvalidname.aspx"&gt;IsValidName&lt;/a&gt; method returns a Boolean and does not throw any exceptions.  The &lt;a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.inamecreationservice.validatename.aspx"&gt;ValidateName&lt;/a&gt; method can throw an exception to return the exact reason why the candidate name fails.  Generally, the code structure of the two methods should be similar, differing primarily in how they communicate an error back to the developer.&lt;/p&gt;&lt;pre class="code"&gt;&lt;font size="1"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;INameCreationService&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;IsValidName(&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; name)
    {
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Cannot be null or empty
&lt;/span&gt;      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;IsNullOrEmpty(name))
      {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;;
      }
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Cannot start with a number
&lt;/span&gt;      &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt; uc &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Char&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetUnicodeCategory(name, &lt;span style="color: rgb(255,0,255)"&gt;0&lt;/span&gt;);
      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (uc &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;DecimalDigitNumber)
      {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;;
      }
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Cannot have anything other than letters and numbers
&lt;/span&gt;      &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Char&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; name)
      {
        uc &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Char&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetUnicodeCategory(c);
        &lt;span style="color: rgb(0,0,255)"&gt;switch&lt;/span&gt; (uc)
        {
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;UppercaseLetter:
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;LowercaseLetter:
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;TitlecaseLetter:
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;DecimalDigitNumber:
            &lt;span style="color: rgb(0,0,255)"&gt;break&lt;/span&gt;;
          &lt;span style="color: rgb(0,0,255)"&gt;default&lt;/span&gt;:
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;;
        }
      }
      &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;;
    }
&lt;/font&gt;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;font size="1"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;INameCreationService&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;ValidateName(&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; name)
    {
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Cannot be null
&lt;/span&gt;      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (name &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
      {
        &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"name"&lt;/span&gt;);
      }
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Cannot be empty
&lt;/span&gt;      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (name&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Trim()&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;Length &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;0&lt;/span&gt;)
      {
        &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"name cannot be of zero length"&lt;/span&gt;);
      }
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Cannot start with a number
&lt;/span&gt;      &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt; uc &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Char&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetUnicodeCategory(name, &lt;span style="color: rgb(255,0,255)"&gt;0&lt;/span&gt;);
      &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (uc &lt;span style="color: rgb(128,128,0)"&gt;==&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;DecimalDigitNumber)
      {
        &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"name cannot start with a number"&lt;/span&gt;);
      }
      &lt;/font&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Cannot have anything other than letters and numbers
&lt;/span&gt;      &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Char&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; name)
      {
        uc &lt;span style="color: rgb(128,128,0)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Char&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;GetUnicodeCategory(c);
        &lt;span style="color: rgb(0,0,255)"&gt;switch&lt;/span&gt; (uc)
        {
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;UppercaseLetter:
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;LowercaseLetter:
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;TitlecaseLetter:
          &lt;span style="color: rgb(0,0,255)"&gt;case&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;UnicodeCategory&lt;/span&gt;&lt;span style="color: rgb(128,128,0)"&gt;.&lt;/span&gt;DecimalDigitNumber:
            &lt;span style="color: rgb(0,0,255)"&gt;break&lt;/span&gt;;
          &lt;span style="color: rgb(0,0,255)"&gt;default&lt;/span&gt;:
            &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"name must contain only letters and numbers"&lt;/span&gt;);
        }
      }
      &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt;;
    }
&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;While there is a little more refactoring possible, that will be good enough for now.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116143"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116143" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/mtreadwell/aggbug/116143.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mark Treadwell</dc:creator>
            <guid>http://geekswithblogs.net/mtreadwell/archive/2007/10/18/116143.aspx</guid>
            <pubDate>Thu, 18 Oct 2007 23:12:15 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/mtreadwell/comments/116143.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/mtreadwell/archive/2007/10/18/116143.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/mtreadwell/comments/commentRss/116143.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/mtreadwell/services/trackbacks/116143.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom Forms Designer: A Restart</title>
            <link>http://geekswithblogs.net/mtreadwell/archive/2007/10/17/116107.aspx</link>
            <description>&lt;p&gt;Reminder: All posts in this series can be found &lt;a title="Custom Forms Designer Series" href="http://geekswithblogs.net/mtreadwell/category/7229.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Some time ago, I started work on hosting the Windows Forms design surface in a project.  Since that was nearly three years ago, I believe it was in the early .NET 2.0 days.  My priorities got redirected and the project languished.  A new project is clearly targeted at achieving the same goal, so I am back to building a solid implementation to get a beta front end out the door.&lt;/p&gt; &lt;p&gt;Those old posts are still of good use to remind me of everything I have forgotten in the interim:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://geekswithblogs.net/mtreadwell/archive/2004/11/23/15763.aspx"&gt;Implementing a Custom Forms Designer in .NET&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19342.aspx"&gt;.NET Custom Forms Designer: The Goal&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19343.aspx"&gt;.NET Custom Forms Designer: Classes and Interfaces&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://geekswithblogs.net/mtreadwell/archive/2005/01/11/19745.aspx"&gt;.NET Custom Forms Designer: Framework 2.0&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Microsoft has subsequently posted a much more complete MSDN Magazine sample:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/03/DesignerHosting/"&gt;The Perfect Host: Create And Host Custom Designers With The .NET Framework 2.0&lt;/a&gt; (download &lt;a href="http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/DesignerHosting.exe"&gt;code&lt;/a&gt;) &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I am using this sample as the basis for a new project which has a Windows Forms design surface at its heart.  The main application will control the execution of a suite of 30 or so training applications in a standalone network.  The instructor will be able to control everything from a central computer, remote boot the computers, group the computers together into teams/rooms, remote start individual applications on the computers, assign the teams to specific training exercises, monitor the status of the exercises, and remote stop the applications, and remote shut down the computers.&lt;/p&gt; &lt;p&gt;The use of the Windows Forms design surface will allow me to use custom Windows controls to represent the computers, groups, and rooms.  This removes a significant amount of the complexity from the application.  The tradeoff is the implementation of the Windows Forms design surface details are nontrivial, but not too difficult.&lt;/p&gt; &lt;p&gt;The first thing I did with the sample was to customize the code to my layout tastes (Ctrl+E, D), deleting and adding blank lines as I scanned through the files.  Recompile.  Change the namespaces to fit our development scheme.  Recompile after each.  Extract extra types where there was more than one in a file, again to match our standards.  Recompile.  Change the executable names and compile locations.  Recompile.  Add our assembly attributes.  Recompile.  Clean up the using statements at the top of the code files.  Recompile.&lt;/p&gt; &lt;p&gt;OK.  Now I feel like I can do some coding.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116107"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116107" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/mtreadwell/aggbug/116107.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mark Treadwell</dc:creator>
            <guid>http://geekswithblogs.net/mtreadwell/archive/2007/10/17/116107.aspx</guid>
            <pubDate>Thu, 18 Oct 2007 02:02:32 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/mtreadwell/comments/116107.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/mtreadwell/archive/2007/10/17/116107.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/mtreadwell/comments/commentRss/116107.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/mtreadwell/services/trackbacks/116107.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom Forms Designer: Framework 2.0</title>
            <link>http://geekswithblogs.net/mtreadwell/archive/2005/01/11/19745.aspx</link>
            <description>&lt;p&gt;In a comment to an earlier post, Tim Dawson pointed out that there are some significant improvements with respect to design surfaces in the upcoming .NET Framework 2.0.  I was going to get to that after I covered what bits need to be assembled in order to get a design surface to work.  Instead, I will modify my table now to indicate what the new Framework brings.  Here is some info from MSDN2:&lt;/p&gt;
&lt;p&gt;----------&lt;/p&gt;
&lt;p&gt;The new &lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt; class implements what the user perceives as a designer. &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; is the user interface the user manipulates to change design-time features. &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; provides a completely self-contained design surface.&lt;/p&gt;
&lt;p&gt;The &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; class may be used as a stand-alone designer, or it may be coupled with &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/73caby0x.aspx"&gt;DesignSurfaceManager&lt;/a&gt;&lt;/span&gt; to provide a common implementation for an application that hosts multiple &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; objects.&lt;/p&gt;
&lt;p&gt;The &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; class can be used by itself, or the user can derive a new class from it and augment the behavior.&lt;/p&gt;
&lt;p&gt;The &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; class provides several design-time services automatically. The &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; class adds all of its services in its constructor. Most of these services can be overridden by replacing them in the protected &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/c1zw7y4x.aspx"&gt;ServiceContainer&lt;/a&gt;&lt;/span&gt; property. To replace a service, override the constructor, call base, and make any changes through the protected &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/c1zw7y4x.aspx"&gt;ServiceContainer&lt;/a&gt;&lt;/span&gt; property. All services added to the service container that implement &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/aax125c9.aspx"&gt;IDisposable&lt;/a&gt;&lt;/span&gt; are disposed when the design surface is disposed.&lt;/p&gt;
&lt;p&gt;The &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt;&lt;/span&gt; class also provides a single service that is available through a component's site. This service is unique for each component. In addition to &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/bafktt51.aspx"&gt;ISite&lt;/a&gt;&lt;/span&gt;, the site also implements &lt;span class="codeEntityReference"&gt;&lt;a href="http://msdn2.microsoft.com/library/13dk8k8h.aspx"&gt;IDictionaryService&lt;/a&gt; &lt;/span&gt;interface. Check for the existence of this or other interfaces, rather than use indiscriminate casting, because other site implementations may not implement them.&lt;/p&gt;
&lt;p&gt;----------&lt;/p&gt;
&lt;p&gt;The codes for the following tables are as follows:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;DH - Interface is implemented in the DesignerHost class &lt;/li&gt;
    &lt;li&gt;SF - Interface/class is implemented in a separate file &lt;/li&gt;
    &lt;li&gt;NI - Interface is not implemented, but commented stubs do exist &lt;/li&gt;
    &lt;li&gt;DEF - Uses the default implementation of the service &lt;/li&gt;
    &lt;li&gt;DR - &lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt; class provides a default service that is replaceable &lt;/li&gt;
    &lt;li&gt;DN - &lt;a href="http://msdn2.microsoft.com/library/kd7dydka.aspx"&gt;DesignSurface&lt;/a&gt; class provides a default service that is not replaceable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are the classes and non-service interfaces.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="1"&gt;&lt;u&gt;Classes/Interfaces            |MSKB|MSDN|Dawson|2.0| Namespace                                 &lt;/u&gt;&lt;br /&gt;
DesignerAttributeService      | -- | -- |  --  |DR | System.ComponentModel.Design&lt;br /&gt;
DesignerLoader                | SF |    |      |   | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;u&gt;DesignerTransaction           | SF | SF |  SF  |DN | System.ComponentModel.Design               &lt;br /&gt;
&lt;/u&gt;DesignSurface                 | -- | -- |  --  |DR | System.ComponentModel.Design&lt;br /&gt;
IContainer                    | DH | DH |  DH  |   | System.ComponentModel&lt;br /&gt;
&lt;u&gt;IComponent                    |    |    |      |   | System.ComponentModel                      &lt;br /&gt;
&lt;/u&gt;IDesigner                     |    |    |      |   | System.ComponentModel.Design&lt;br /&gt;
IDesignerFilter               |    |    |      |   | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;IDesignerHost                 | DH | DH |  DH  |DN | System.ComponentModel.Design               &lt;br /&gt;
&lt;/u&gt;IDesignerLoaderHost           | DH |    |      |   | System.ComponentModel.Design.Serialization&lt;br /&gt;
IDisposable                   | DH | DH |      |   | System&lt;br /&gt;
&lt;u&gt;IExtenderProvider             | SF |    |  DH  |   | System.ComponentModel                      &lt;br /&gt;
&lt;/u&gt;IRootDesigner                 | SF |    |      |   | System.ComponentModel.Design&lt;br /&gt;
ISite                         | SF | SF |  SF  |   | System.ComponentModel&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;This table shows just the service interfaces that are/can be implemented.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="1"&gt;&lt;u&gt;Service Interfaces            |MSKB|MSDN|Dawson|2.0| Namespace                                 &lt;br /&gt;
&lt;/u&gt;IComponentChangeService       | DH | DH |  DH  |DN | System.ComponentModel.Design&lt;br /&gt;
IDesignerEventService         | DH | DH |      |   | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;IDesignerOptionService        |    |    |      |   | System.ComponentModel.Design               &lt;br /&gt;
&lt;/u&gt;IDesignerLoaderService        |    |    |      |   | System.ComponentModel.Design.Serialization&lt;br /&gt;
IDesignerSerializationManager | SF |    |      |   | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;u&gt;IDesignerSerializationProvider|    |    |      |   | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;/u&gt;IDesignerSerializationService |    |    |      |   | System.ComponentModel.Design.Serialization&lt;br /&gt;
IDictionaryService            | SF | SF |  SF  |DN | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;IEventBindingService          | SF |    |      |   | System.ComponentModel.Design               &lt;br /&gt;
&lt;/u&gt;IExtenderListService          |    |    |  DH  |DR | System.ComponentModel.Design&lt;br /&gt;
IExtenderProviderService      | DH | DH |  DH  |DR | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;IHelpService                  | NI |    |      |   | System.ComponentModel.Design               &lt;br /&gt;
&lt;/u&gt;IMenuCommandService           | SF | SF |  SF  |   | System.ComponentModel.Design&lt;br /&gt;
IMenuEditorService            | NI |    |      |   | System.Windows.Forms.Design&lt;br /&gt;
&lt;u&gt;INameCreationService          | DEF| SF |  SF  |   | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;/u&gt;IPropertyValueUIService       | NI |    |      |   | System.Drawing.Design&lt;br /&gt;
IReferenceService             | NI |    |      |DR | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;IResourceService              | SF |    |      |   | System.ComponentModel.Design               &lt;br /&gt;
&lt;/u&gt;ISelectionService             | SF | SF |  SF  |DR | System.ComponentModel.Design&lt;br /&gt;
IServiceContainer             | DH | DH |  DH  |DN | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;IServiceProvider              | DH | DH |  SF  |DN | System                                     &lt;br /&gt;
&lt;/u&gt;IToolboxService               | SF | SF |  SF  |   | System.Drawing.Design&lt;br /&gt;
ITypeDescriptorFilterService  | SF | SF |  DH  |DR | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;ITypeResolutionService        | SF |    |      |   | System.ComponentModel.Design               &lt;br /&gt;
&lt;/u&gt;IUIService                    |    |    |  SF  |   | System.Windows.Forms.Design&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Next: What do these default services and classses do in support of the new DesignSurface class?&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19745"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19745" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/mtreadwell/aggbug/19745.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mark Treadwell</dc:creator>
            <guid>http://geekswithblogs.net/mtreadwell/archive/2005/01/11/19745.aspx</guid>
            <pubDate>Wed, 12 Jan 2005 02:10:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/mtreadwell/comments/19745.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/mtreadwell/archive/2005/01/11/19745.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/mtreadwell/comments/commentRss/19745.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/mtreadwell/services/trackbacks/19745.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom Forms Designer: Classes and Interfaces</title>
            <link>http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19343.aspx</link>
            <description>&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;DH  – Interface is implemented in the DesignerHost class &lt;/li&gt;
    &lt;li&gt;SF  – Interface/class is implemented in a separate file &lt;/li&gt;
    &lt;li&gt;NI  – Interface is not implemented, but commented stubs do exist &lt;/li&gt;
    &lt;li&gt;DEF – Uses the default implementation of the service&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are the classes and non-service interfaces.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="1"&gt;&lt;u&gt;&lt;strong&gt;Classes/Interfaces             | MSKB | MSDN | Dawson|&lt;br /&gt;
&lt;/strong&gt;&lt;/u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignserializationdesignerloaderclasstopic.asp"&gt;DesignerLoader&lt;/a&gt;                 |  SF  |      |       | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesigndesignertransactionclasstopic.asp"&gt;DesignerTransaction&lt;/a&gt;            &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  SF  |  SF  |  SF   |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelIContainerClassTopic.asp"&gt;IContainer&lt;/a&gt;                     &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  DH  |  DH  |  DH   |&lt;/font&gt;&lt;/u&gt; System.ComponentModel&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelIComponentClassTopic.asp"&gt;IComponent&lt;/a&gt;                     |      |      |       | System.ComponentModel&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIDesignerClassTopic.asp"&gt;IDesigner&lt;/a&gt;                      |      |      |       | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIDesignerFilterClassTopic.asp"&gt;IDesignerFilter&lt;/a&gt;                |      |      |       |&lt;/u&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIDesignerHostClassTopic.asp"&gt;IDesignerHost&lt;/a&gt;&lt;/font&gt;                  &lt;/font&gt;&lt;font color="#ff0000"&gt;|  DH  |  DH  |  DH   |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignserializationidesignerloaderhostclasstopic.asp"&gt;IDesignerLoaderHost&lt;/a&gt;            |  DH  |      |       | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemidisposableclasstopic.asp"&gt;IDisposable&lt;/a&gt;                    |  DH*1|  DH*1|       |&lt;/u&gt; System&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeliextenderproviderclasstopic.asp"&gt;IExtenderProvider&lt;/a&gt;              |  SF  |      |  DH   | System.ComponentModel&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIRootDesignerClassTopic.asp"&gt;IRootDesigner&lt;/a&gt;                  |  SF  |      |       | System.ComponentModel.Design&lt;br /&gt;
&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelISiteClassTopic.asp"&gt;ISite&lt;/a&gt;                          &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  SF*4|  SF*3|  SF*2 |&lt;/font&gt; System.ComponentModel&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;This table shows just the service interfaces that are/can be implemented.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="1"&gt;&lt;u&gt;&lt;strong&gt;Service Interfaces             | MSKB | MSDN | Dawson|&lt;br /&gt;
&lt;/strong&gt;&lt;/u&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIComponentChangeServiceClassTopic.asp"&gt;IComponentChangeService&lt;/a&gt;        &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  DH  |  DH  |  DH   |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIDesignerEventServiceClassTopic.asp"&gt;IDesignerEventService&lt;/a&gt;          |  DH  |  DH  |       | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIDesignerOptionServiceClassTopic.asp"&gt;IDesignerOptionService&lt;/a&gt;         |      |      |       |&lt;/u&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignserializationidesignerloaderserviceclasstopic.asp"&gt;IDesignerLoaderService&lt;/a&gt;         |      |      |       | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignserializationidesignerserializationmanagerclasstopic.asp"&gt;IDesignerSerializationManager&lt;/a&gt;  |  SF  |      |       | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignserializationidesignerserializationproviderclasstopic.asp"&gt;IDesignerSerializationProvider&lt;/a&gt; |      |      |       |&lt;/u&gt; System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignSerializationIDesignerSerializationServiceClassTopic.asp"&gt;IDesignerSerializationService&lt;/a&gt;  |      |      |       | System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIDictionaryServiceClassTopic.asp"&gt;IDictionaryService&lt;/a&gt;             &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  SF*4|  SF*3|  SF*2 |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignieventbindingserviceclasstopic.asp"&gt;IEventBindingService&lt;/a&gt;           |  SF  |      |       |&lt;/u&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIExtenderListServiceClassTopic.asp"&gt;IExtenderListService&lt;/a&gt;           |      |      |  DH   | System.ComponentModel.Design&lt;br /&gt;
&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIExtenderProviderServiceClassTopic.asp"&gt;IExtenderProviderService&lt;/a&gt;       &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  DH  |  DH  |  DH   |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignihelpserviceclasstopic.asp"&gt;IHelpService&lt;/a&gt;                   |  NI  |      |       |&lt;/u&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIMenuCommandServiceClassTopic.asp"&gt;IMenuCommandService&lt;/a&gt;            &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  SF  |  SF  |  SF   |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWindowsFormsDesignIMenuEditorServiceClassTopic.asp"&gt;IMenuEditorService&lt;/a&gt;             |  NI  |      |       | System.Windows.Forms.Design&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignSerializationINameCreationServiceClassTopic.asp"&gt;INameCreationService&lt;/a&gt;           |  DEF |  SF  |  SF   |&lt;/u&gt; System.ComponentModel.Design.Serialization&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemdrawingdesignipropertyvalueuiserviceclasstopic.asp"&gt;IPropertyValueUIService&lt;/a&gt;        |  NI  |      |       | System.Drawing.Design&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesignireferenceserviceclasstopic.asp"&gt;IReferenceService&lt;/a&gt;              |  NI  |      |       | System.ComponentModel.Design&lt;br /&gt;
&lt;u&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemcomponentmodeldesigniresourceserviceclasstopic.asp"&gt;IResourceService&lt;/a&gt;               |  SF  |      |       |&lt;/u&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignISelectionServiceClassTopic.asp"&gt;ISelectionService&lt;/a&gt;              &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  SF  |  SF  |  SF   |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignIServiceContainerClassTopic.asp"&gt;IServiceContainer&lt;/a&gt;              &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  DH*1|  DH  |  DH*1 |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemIServiceProviderClassTopic.asp"&gt;&lt;u&gt;IServiceProvider&lt;/u&gt;&lt;/a&gt;&lt;/font&gt;&lt;u&gt;&lt;font color="#000000"&gt;               &lt;/font&gt;&lt;font color="#ff0000"&gt;|  DH*1|  DH*1|  SF*2 |&lt;/font&gt;&lt;/u&gt;&lt;/font&gt; System&lt;br /&gt;
&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDrawingDesignIToolboxServiceClassTopic.asp"&gt;IToolboxService&lt;/a&gt;                &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  SF  |  SF  |  SF   |&lt;/font&gt; System.Drawing.Design&lt;br /&gt;
&lt;font color="#0000ff"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignITypeDescriptorFilterServiceClassTopic.asp"&gt;ITypeDescriptorFilterService&lt;/a&gt;   &lt;/font&gt;&lt;/font&gt;&lt;font color="#ff0000"&gt;|  SF  |  SF  |  DH   |&lt;/font&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New" size="1"&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemComponentModelDesignITypeResolutionServiceClassTopic.asp"&gt;&lt;u&gt;ITypeResolutionService&lt;/u&gt;&lt;/a&gt;&lt;u&gt;         |  SF  |      |       |&lt;/u&gt; System.ComponentModel.Design&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwindowsformsdesigniuiserviceclasstopic.asp"&gt;IUIService&lt;/a&gt;                     |      |      |  SF   | System.Windows.Forms.Design&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="1"&gt;  *1 - Omitted from the class definition&lt;br /&gt;
  *2 – Implemented in DesignSite.cs&lt;br /&gt;
  *3 - Implemented in SiteImpl.cs&lt;br /&gt;
  *4 - Implemented in SampleDesignSite.cs&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19343"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19343" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/mtreadwell/aggbug/19343.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mark Treadwell</dc:creator>
            <guid>http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19343.aspx</guid>
            <pubDate>Fri, 07 Jan 2005 04:12:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/mtreadwell/comments/19343.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19343.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/mtreadwell/comments/commentRss/19343.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/mtreadwell/services/trackbacks/19343.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom Forms Designer: The Goal</title>
            <link>http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19342.aspx</link>
            <description>&lt;p&gt;My &lt;a href="http://geekswithblogs.net/mtreadwell/archive/2004/11/23/15763.aspx"&gt;previous post&lt;/a&gt; on a .NET custom forms designer was a basic listing of the samples that are out there and some of their merits.  It was not an exceptionally enlightened piece, so I intend to correct a few things and add some additional detail over the next couple of weeks.  I included a listing of interfaces and made an unfulfilled hint at completing a full-featured design surface.  I’ll get to the point eventually, so bear with me on this.  We are off on a voyage of discovery....&lt;/p&gt;
&lt;p&gt;I listed five examples of design surfaces in that first post.  I will be throwing out two of them from consideration, but for different reasons.  The first to be tossed is the &lt;a href="http://msdn.microsoft.com/library/en-us/dndotnet/html/designsurface.asp"&gt;MSDN GDI+ sample&lt;/a&gt;.  This does not interact with the core .NET designer and is actually a poor substitute at trying to emulate it.  It is OK for what it tries to do, but it does not fit my ultimate goal, which I’ll get to shortly.&lt;/p&gt;
&lt;p&gt;The second example to be tossed is &lt;a href="http://www.icsharpcode.net/OpenSource/SD/"&gt;SharpDevelop&lt;/a&gt;.  I am not trying to recreate Visual Studio as they are.  SharpDevelop also has what can only be called an intricate extensible structure of "codons".  Their extensibility structure seems to have created lots of additional work with little perceivable benefit.  Perhaps I’m wrong.  Anyway, you are welcome to look at their work, but the GPL restrictions were enough to turn me off.&lt;/p&gt;
&lt;p&gt;That leaves us with three samples.  For ease of reference, I’ll shorten their names as follows:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Dawson - DivElements, &lt;a href="http://www.divil.co.uk/net/articles/designers/hosting.asp"&gt;Hosting Windows Forms Designers&lt;/a&gt; (June 2003) &lt;/li&gt;
    &lt;li&gt;MSKB - Microsoft Knowledgebase, &lt;a href="http://support.microsoft.com/?id=813808"&gt;INFO: Code Sample That Demonstrates How to Create a Custom Form Designer by Using Visual C# .NET&lt;/a&gt; (August 2004) &lt;/li&gt;
    &lt;li&gt;MSDN - MSDN Magazine, &lt;a href="http://msdn.microsoft.com/msdnmag/issues/04/12/CustomFormsDesigner/default.aspx"&gt;.NET Internals: Tailor Your Application by Building a Custom Forms Designer with .NET&lt;/a&gt; (December 2004) &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From these three samples, I intend to work towards a Windows Forms design surface that I will be able to then customize for my specific application.  Therefore my goal is a rich design environment that will permit my users to create custom forms.  Eventually, I'll create some custom controls and restrict them to only using those, but that is far in the future.  In the meantime, I need to create a designer.&lt;/p&gt;
&lt;p&gt;I need to make a few corrections to my &lt;a href="http://geekswithblogs.net/mtreadwell/archive/2004/11/23/15763.aspx"&gt;earlier comments&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The Dawson sample consists of code and a brief accompanying article.  There is some depth to parts of the discussion, but it does not cover things in detail.  Overall, it is great and was the first published effort I found.  The presented sample is very rough, but it works.  The toolbox is actually a Listbox with the names of the controls.  There is simple functionality.&lt;/p&gt;
&lt;p&gt;The MSDN sample is far ahead of the Dawson version.  Interestingly, I wondered if they came from the same code base, since there were some amazing similarities I saw.  The MSDN toolbox is a Treeview with drag-and-drop functionality.  Tools and icons are loaded from those installed on the user’s machine with the framework.  Functionality is much better.&lt;/p&gt;
&lt;p&gt;The MSKB sample is actually the best of the three.  There is no real accompanying article, but the code is well-commented.  In fact, the code appears to have been excised from a larger, more-finished program.  There are several stubs present for additional interface implementations.  These may well be the remains of routines left after custom code was removed, but their retention is appreciated.  Many of the comments look suspiciously like the remains of XML comments that have had their XML wrappers deleted.  This sample has by far the best functionality.  Keyboard and menu commands are included.  Code display in both VB and C# is supported.  The toolbox looks much like Visual Studio’s and supports both mouse and keyboard.  Overall, it wins as the most complete example.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19342"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19342" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/mtreadwell/aggbug/19342.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Mark Treadwell</dc:creator>
            <guid>http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19342.aspx</guid>
            <pubDate>Fri, 07 Jan 2005 03:29:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/mtreadwell/comments/19342.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/mtreadwell/archive/2005/01/06/19342.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/mtreadwell/comments/commentRss/19342.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/mtreadwell/services/trackbacks/19342.aspx</trackback:ping>
        </item>
    </channel>
</rss>