locked
UserControl, Inherited Control, Abstract class, (C#) RRS feed

  • Question

  • Hi all,
    this question may not be directly related to the controls used the window, it has to do with my object-oriented design I suppose.

    Any help is appreciated!

    Alright, I have a User Control (call it MainUserControl), and several Inherited User Controls that inherit from the MainUserControl.
    I do have couple methods that Inherited User Controls must implement, so I decide to do it using an interface and an abstract class.

    Apparently I am having trouble, it won't work if i have this following chain

    InterfaceClass
    AbstractClass : UserControl, InterfaceClass
    MainUserControlClass : AbstractClass
    InheritedUserControlClass : MainUserControlClass

    This results the design view of Inherited User Controls no longer can be viewerd (it displayed an error, saying can't create an instance of an abstract class, which I already know).

    If you want it to work properly, the MainUserControl must inherits UserControl DIRECTLY
    i.e.
    MainUserControlClass : UserControl
    InheritedUserControlClass : MainUserControlClass


    Now I tried to do this way

    MainUserControlClass : UserControl, InterfaceClass
    But this is not what I want, because in the MainUserControlClass, i know it is forced to implement the interface, but this structure will not force the Inherited User Controls to implement the interface.

    **Remember, the main goal is to force the Inherited User Controls to implement the interface, but the user controls and inherited user controls seem to be giving me problems.




    Monday, March 17, 2008 2:12 PM

Answers

  • thank philip for your input.

    it turned out that my way of doing it still compiles, and works fine during runtime.

    it's just that doing my way, the designer's view won't be able to display properly, because it can't instanitiate an abstract class.

     

    Thursday, March 20, 2008 5:38 PM

All replies

  • I'd like to see the code that uses

    InterfaceClass
    AbstractClass : UserControl, InterfaceClass
    MainUserControlClass : AbstractClass
    InheritedUserControlClass : MainUserControlClass

     

    I  have the feeling you are overdoing it. Maybe you don't need an interface at all.

    Nevertheless it should work. If you cannot instantiate what you want to instantiate, that would mean that you still have to implement one of the abstract methods or one of the interface methods.

    Wednesday, March 19, 2008 10:25 AM
  • thank philip for your input.

    it turned out that my way of doing it still compiles, and works fine during runtime.

    it's just that doing my way, the designer's view won't be able to display properly, because it can't instanitiate an abstract class.

     

    Thursday, March 20, 2008 5:38 PM
  • I've run into similar problems, and I just now found a solution to this which isn't ideal, but works pretty well.  I think you've hit on the problem, and that's that the designer pulls from the direct parent as the basis for the control design.  So abstact controls show up just fine in the designer (because they probably pull from something like a UserControl), but controls inherited from abstract controls don't.

     

    The solution I found was posted in another forum, but I can't remember which one (so I apologize for not giving due credit to whomever this belongs), but the general idea was to use pre-compiler directives (I believe they're called) to allow for design-time editing during debug, but turning that off during Release compile.  So you could do something like this for your class base class declaration (in C#):

     

    #if DEBUG

    public class MyControl : UserControl, IInterface

    #else

    public abstract class MyControl : UserControl, IInterface

    #endif

     

    Then, if you have abstract methods, you can do something very similar with those:

     

    #if DEBUG

    public virtual void DoStuff()

    {

    throw new NotImplementedException();

    }

    #else

    public abstract void DoStuff();

    #endif

     

    This way, the child control(s) show up in the Designer which is often very handy during Debug development, but during a release build, the proper checks will be in place to keep the abstract rules in place.

     

    The drawback here is that this introduces quite a bit of distinction between the compile modes which can lead to subtle errors.  All of these should show up during a Release build, but it could still be a pain if Debug allows you to inherit from things Release would -- correctly -- balk at.  I don't know how your enviroment works, but for me, Release is almost more of a formality than anything, and swapping to Relase mode is supposedly very trivial.  If I swapped over and suddely had a long list of errors, it would probably throw me for a loop.  Hopefully the NotImplementedExceptions will help find these bugs during Debug, and make for few, if any, changes during a Release build.

    Monday, April 28, 2008 3:34 PM
  • I'm assuming that in your abstract class you are declaring it as abstract: public abstract partial class MainUserControlClass

    Which is exactly what I did at first. After all, if you want a class that is to be inherited from, this is what you do.

    For whatever reasons, when it comes to controls, you don't do this. Take 'abstract' out of your class declaration and it will work. How InheritedUserControlClass can inherit from something that isn't abstract, I don't know.

    I figured this out by reading http://msdn.microsoft.com/en-us/library/a6h7e207(v=vs.100).aspx

    There's a section at the bottom called Inheriting from a Composite Control. I noticed in this section that they didn't have you change the bases class to abstract nor did they instruct you to author it as abstract originally.

    • Proposed as answer by ThreePly Thursday, April 12, 2012 6:03 PM
    Thursday, April 12, 2012 6:03 PM