in

Platinum Bay

Peace, Love and Visual Studio Team System

.NETicated

Designing Windows Forms with Abstract Inheritance

I got sick of Notepad a couple weeks ago, and set about to build a Notepad-like application with a couple sorely missing features like reload prompting, multiple undo levels, tabs, line numbers, more robust find and replace, recent files list, opacity, etc. It's a cool little project, titled DevNotepad, and is currently about 3,000 lines of code. It's fast too, which is very important for a Notepad replacement. The beauty of Notepad itself is its compact size and loading speed. More on DevNotepad later.

Along the way though, I ran into a problem trying to visually design user controls which inherited from an abstract class. Out of the install (box), Visual Studio does not support this. If you were to try and visually design a form which inherits from an abstract class, you would get a message similar to the following:

After digging through [your favorite search engine], I found it is possible to modify this behavior. The key is to provide a TypeDescriptionProvider attribute to the base abstract class:

[TypeDescriptionProvider(typeof(SubstituteBaseUserControlProvider))]
public abstract class BaseUserControl : UserControl
...

If you don't have Reflector installed, TypeDescriptorProvider is in the System.ComponentModel namespace. The next step is to build the actual provider itself:

internal class ReplaceOptionsPageProvider : TypeDescriptionProvider

   
public ReplaceOptionsPageProvider()
       
: base(TypeDescriptor.GetProvider(typeof(BaseOptionsPage)))
   
{
    }

    public override Type GetReflectionType(Type objectType, object instance)
   
{
       
if (objectType == typeof (BaseOptionsPage))
           
return typeof (ReplaceForm);

       
return base.GetReflectionType(objectType, instance);
   
}

   
public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
   
{
       
if (objectType == typeof (BaseOptionsPage))
           
objectType = typeof (ReplaceForm);

        return base.CreateInstance(provider, objectType, argTypes, args);
   
}
}

The above code detects if the user control to be designed inherits from the aforementioned abstract class, and gives it a replacement to start designing from – a stand-in base class. Therefore, the final step is to build the stand-in user control, inheriting from the original abstract class:

internal class StandInUserControl : BaseOptionsPage

Once the code is in place, close any open designer windows, rebuild the project, and re-open the previously troublesome designer. You should be good to go.

Hope this helps

Comments

No Comments

Leave a Comment

(required )  
(optional )
(required )  
Add

About Steve

Steve Andrews has been working as a developer for more than 8 years. During this time, he has designed and developed applications in such widely varying areas as trust accounting, medical information management, supply chain management, and retail systems. He has firsthand developer experience with a variety of languages, including Java, VB, and .NET. Most recently, he has been immersed in SharePoint. He is currently employed at RDA Corporation in Philadelphia, PA, as a Software Engineer and a team member in the Architectural Guidance evangelism team. Steve is also an MTCS (x2), ICSOO, and .NET fanatic.
Powered by Community Server (Commercial Edition), by Telligent Systems
© Platinum Bay | Some Rights Reserved Creative Commons License

Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Feel free to challenge me, disagree with me, or tell me I'm completely nuts in the comments section of each blog entry, but I reserve the right to delete any comment for any reason whatsoever (abusive, profane, rude, or annonymous comments) - so keep it polite, please.