Multiple derivations from UserControl

S

steve.kaye

I am writing a number of controls which use inheritance and I have a
problem that I do not know how to solve. It's best if I describe the
class structure I want.

Grid - derives from UserControl and contains most of the functionality
required of a basic grid.

ViewGrid, EditGrid and TreeGrid - all derive from Grid

The problem I have is that I never want the programmer to create an
object of type Grid - they should choose the derived class that best
fits their needs.

If these were normal classes then I would just declare the Grid class
as abstract and it would work as I would like it to. The problem is
that they derive from UserControl and the designer needs to create an
instance of Grid when I view EditGrid in the designer.

Another idea I had was to declare the Grid class as protected or
internal but then I cannot derive a public class from it.

Is there a way to specify that a UserControl derived class cannot be
created outside of the assembly that it is in and still enable it to be
created by the designer?

steve.kaye
 
B

Bjorn Abelli

...
If these were normal classes then I would just declare the Grid class
as abstract and it would work as I would like it to. The problem is
that they derive from UserControl and the designer needs to create an
instance of Grid when I view EditGrid in the designer.

I don't know why it needs to instantiate from Grid in your case. I have
abstract controls that I have been able to edit subclasses to in the
designer. Maybe you at some point instantiate it by "composition" in your
class EditGrid.

Anyway...
Another idea I had was to declare the Grid class as protected or
internal but then I cannot derive a public class from it.

You can declare the constructor of Grid internal.

// Bjorn A
 
S

steve.kaye

Bjorn said:
...


I don't know why it needs to instantiate from Grid in your case. I have
abstract controls that I have been able to edit subclasses to in the
designer. Maybe you at some point instantiate it by "composition" in your
class EditGrid.

I've not been programming in .NET for long so could you tell me what
you mean by "instantiate it by "composition" "?

I have just tried this:

1) Start a new windows control library.
2) Rename the UserControl1 class to be BaseControl.
3) Change the BaseControl class to be abstract.
4) Build.
5) Add an Inherited UserControl to the project.

At this stage it would ask me to specify a class to derive from but it
warns me that no built assemblies contain components to inherit from
and advises me to build the current application or browse for a
previously built assembly from another application.

You can declare the constructor of Grid internal.

This works but not as nicely as I would like. It still allows the
programmer to drag a Grid onto the form but it doesn't create the
object in InitializeComponent() because the constructor is not
accessible. I could use this method along with a comment in the
description of the control to not use it but use a derived class but I
would much rather avoid having the object in the toolbox to start with.

steve.kaye
 
B

Bjorn Abelli

I've not been programming in .NET for long so could you tell me what
you mean by "instantiate it by "composition" "?

It can mean a lot of things...

A control is in many cases "composed" of other controls (buttons,
textfields, etc).

What I meant in this case was if you on your EditGrid possibly had put an
instance of Grid itself. I can't see any other reason for EditGrid to
complain on an instantiation of Grid.

I still believe you should be able to declare Grid abstract.
I have just tried this:

1) Start a new windows control library.
2) Rename the UserControl1 class to be BaseControl.
3) Change the BaseControl class to be abstract.
4) Build.
5) Add an Inherited UserControl to the project.

At this stage it would ask me to specify a class to derive from but it
warns me that no built assemblies contain components to inherit from
and advises me to build the current application or browse for a
previously built assembly from another application.

Never happened to me.

My VS automagically detects which controls the project already has, and lets
me choose which one I want to inherit from.
This works but not as nicely as I would like. It still allows the
programmer to drag a Grid onto the form but it doesn't create the
object in InitializeComponent() because the constructor is not
accessible. I could use this method along with a comment in the
description of the control to not use it but use a derived class but I
would much rather avoid having the object in the toolbox to start with.

Didn't happen to me either.

I don't know if I have a bug somewhere in my VS, but when I add the library
to my toolbox, somehow it seems to detect that the control with only an
internal constructor cannot be instantiated, hence only shows the derivated
controls.

// Bjorn A
 
S

steve.kaye

Bjorn said:
I don't know if I have a bug somewhere in my VS, but when I add the library
to my toolbox, somehow it seems to detect that the control with only an
internal constructor cannot be instantiated, hence only shows the derivated
controls.

Are you deriving your controls from UserControl or from Control? I
have just tried the simple controls test but derived the base from
Control instead of UserControl and I was able to make the class
abstract and it disappeared from the toolbax which is what I wanted.

I didn't get the same behaviour with the internal constructor. It
still had it on my toolbox and allowed me to add it to the form but
without the grid1 = new Grid() bit.

I'll have a look into what I need to do extra when deriving from
Control rather than UserControl.

Thanks

steve.kaye
 
S

steve.kaye

Bjorn said:
I don't know if I have a bug somewhere in my VS, but when I add the library
to my toolbox, somehow it seems to detect that the control with only an
internal constructor cannot be instantiated, hence only shows the derivated
controls.

Are you deriving your controls from UserControl or from Control? I
have just tried the simple controls test but derived the base from
Control instead of UserControl and I was able to make the class
abstract and it disappeared from the toolbax which is what I wanted.

I didn't get the same behaviour with the internal constructor. It
still had it on my toolbox and allowed me to add it to the form but
without the grid1 = new Grid() bit.

I'll have a look into what I need to do extra when deriving from
Control rather than UserControl.

Thanks

steve.kaye
 
S

steve.kaye

steve.kaye said:
Are you deriving your controls from UserControl or from Control? I
have just tried the simple controls test but derived the base from
Control instead of UserControl and I was able to make the class
abstract and it disappeared from the toolbax which is what I wanted.

I have encountered the same problem with the Control class now. MSDN
says that the base class of the object being passed to the designer is
not allowed to be abstract.

steve.kaye
 
B

Bjorn Abelli

"steve.kaye" wrotw...
Are you deriving your controls from UserControl or from Control?

In this tryout I derived from UserControl.
I have just tried the simple controls test but derived the base from
Control instead of UserControl and I was able to make the class
abstract and it disappeared from the toolbax which is what I wanted.

Nice that it worked out for you.
I didn't get the same behaviour with the internal constructor. It
still had it on my toolbox and allowed me to add it to the form but
without the grid1 = new Grid() bit.

I'll have a look into what I need to do extra when deriving from
Control rather than UserControl.

What you'll be missing depends on what you need... ;-)

Maybe you could try to derive from ContainerControl instead (the immediate
superclass of UserControl). You'll miss less features that way.

// Bjorn A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top