views:

406

answers:

2

I have a base class, defined as below (I'm also using DevExpress components):

public abstract partial class BaseFormClass<R> : XtraForm where R : DataRow
{
  ...
}

Contrary to what I've read from elsewhere, I'm still able to design this class. I didn't have to create a concrete class from it to do so. But, when I create a concrete class descended from it (as below), that class won't work in the designer.

public partial class ConcreteFormClass : BaseFormClass<StronglyTypedRow>
{
  ...
}

I get this message:

The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: ConcreteFormClass --- The base class 'BaseFormClass' could not be loaded. Ensure the assembly has been referenced and that all projects have been built.

Has anyone seen this before? Any sort of known workaround?

+2  A: 

Sorry, but this just isn't going to work (which is a shame -- I've wished in the past that you could do this, too.) The problem is the basic methodology of the designer.

To present you with a model of your form, it doesn't actually try to construct the form itself; if it did that, you'd run into other problems -- what if your form doesn't have a parameterless constructor? Instead, it actually instantiates an instance of the base class of your form. Then it sweeps through your InitializeComponents() method and "layers on" all the controls that you've defined there onto the base form.

So it's obvious why this won't work. You can design an instance of BaseFormClass, because to design that, it creates an instance of XtraForm, which is concrete. But you can't design an instance of ConcreteFormClass, because to do so, it would need to create an instance of BaseFormClass, which is abstract.

The easiest workaround for this is to just make BaseFormClass non-abstract. (If you want to make absolutely sure nobody can create one, perhaps you could make the default constructor private? I'm not sure if the designer can handle that, but I don't see why it couldn't.) Sucks, but such is life. Complain to Microsoft and maybe it'll be better in Visual Studio 2012.

mquander
Thanks, but now I tried using conditional compilation, turning the class concrete, and turning its abstract members virtual. I'm still getting the same message. The reason I made it abstract was not to prevent instantiation, but because I have abstract members whose implementation is dependent on the concrete class. Thanks for the quick response, though.
Dov
I resigned myself to not designing the descended classes. It wasn't necessary, and I had to change my architecture a little, but it's not a wholly bad thing. Thanks for helping me not to waste too much time attempting the impossible.
Dov
Check out mine and smelch's solution, linked in my answer
Allen
A: 

This sounds like a really similar issue to getting the designer to render forms that have an abstract base class. I haven't done any generic multi inheritance but you could at least try my approach and see if it works.

Edit: Yep, ok, just tried it, my solution works for sure. You just have to modify the middle classes definition and the forms definition (wrapped in the #if DEBUG)

Let me know if you're able to try it!

Allen
I mentioned in my initial comment to the accepted answer that I had tried conditional compilation at that point in time, but that was more of an inconvenience than not being able to use the designer. Thanks for the suggestion, though. Maybe that will work for someone else with the same question.
Dov
I may be thinking of the wrong thing, but how is conditional compilation a problem? Or were you just not able to get it to work? As long as you dont need to design in release mode and as long as you dont release debug code to production (which you shouldnt) it will work seamlessly
Allen