Constructors and UserControls

A

Alberto

In a user control I have this constructors:

public Nodo()
{
InitializeComponent();
}

public Nodo(string Texto)
{
InitializeComponent();
this.Text = Texto;
}

And in a class declared as public Element: Nodo I have this
constructors:

public Element()
{
InitializeComponent();
}

public Elemento(string Texto): base(Texto)
{
InitializeComponent();
}

When I try to see design of de Element class, VS says that can't find a
constructor in the base class (Nodo).
Does anybody know why? Thank you
 
P

Peter Duniho

[...]
When I try to see design of de Element class, VS says that can't find a
constructor in the base class (Nodo).
Does anybody know why? Thank you

What version of Visual Studio? Are you sure you've posted _exactly_ the
code you're using?

I created two classes, one that inherits UserControl, and a second that
inherits the first. I created new constructors for each class just as
you've shown here. Both classes work just fine, in design mode for the
individual classes as well as when using either class as a control when
designing some other class (e.g. a Form sub-class).

I'm using VS 2008. It's possible (though unlikely IMHO) that the Designer
in earlier versions of VS have problems with your scenario. If you are
not using 2008, you should install the 2008 version and see if the problem
still occurs (use the Express version, which you can download from
Microsoft's web site, if you don't have ready access to the retail
version).

If you are using VS 2008 and cannot resolve the problem with my assurance
that the code you posted does in fact work generally, then you need to
post a concise-but-complete code example that reliably demonstrates the
problem.

Pete
 
A

Alberto

I just repeated the code in a new project. I did this:
1) Create a new Windows Form project.
2) Create a new UserControl called A only with this code:

public partial class A : Panel
{
private string texto;

public A()
{
InitializeComponent();
}

public A(string Text)
{
InitializeComponent();
texto = Text;
}
}

3) Create a new User Control called B with this code:

public partial class B : A
{
public B()
{
InitializeComponent();
}

public B(string Texto)
: base(Texto)
{
InitializeComponent();
}
}

With this code, when I try to see the design of the control B, I see an
error who says that the base class of A couldn't be loaded. I'm using VS
2008

Thank you


Peter Duniho said:
[...]
When I try to see design of de Element class, VS says that can't find a
constructor in the base class (Nodo).
Does anybody know why? Thank you

What version of Visual Studio? Are you sure you've posted _exactly_ the
code you're using?

I created two classes, one that inherits UserControl, and a second that
inherits the first. I created new constructors for each class just as
you've shown here. Both classes work just fine, in design mode for the
individual classes as well as when using either class as a control when
designing some other class (e.g. a Form sub-class).

I'm using VS 2008. It's possible (though unlikely IMHO) that the Designer
in earlier versions of VS have problems with your scenario. If you are
not using 2008, you should install the 2008 version and see if the problem
still occurs (use the Express version, which you can download from
Microsoft's web site, if you don't have ready access to the retail
version).

If you are using VS 2008 and cannot resolve the problem with my assurance
that the code you posted does in fact work generally, then you need to
post a concise-but-complete code example that reliably demonstrates the
problem.

Pete
 
P

Peter Duniho

I just repeated the code in a new project. I did this:
1) Create a new Windows Form project.
2) Create a new UserControl called A only with this code:

public partial class A : Panel

Your post is self-contradictory. You claim to be creating a UserControl,
but the code you posted here shows you inheriting Panel instead.
[...]
3) Create a new User Control called B with this code:

public partial class B : A

Likewise, since A inherits Panel, B is also a Panel, not a UserControl.
[...]
With this code, when I try to see the design of the control B, I see an
error who says that the base class of A couldn't be loaded. I'm using VS
2008

You need to post a _complete_ code example, along with a more specific
description of what you're trying to do. The phrase "try to see the
design of the control B" is ambiguous. A class inheriting Panel can't
itself be designed at all; it can only be placed within some Form or
UserControl by the Designer. A UserControl can be designed, but your code
examples don't show you inheriting UserControl.

I have attempted to recreate the most obvious interpretation of your
posts, two different ways: with the base class inheriting UserControl, and
with it inheriting Panel. In both cases, I have no trouble at all. No
errors, no problems. Everything works just as I expect it to.

Please take more time and care with your question, to make sure that a)
the question actually makes sense rather than contradicts itself, and b)
that you have posted a code example that is both concise and complete.

Pete
 
A

Alberto

I added an user control and I changed the :UserControl for :panel.
You need to post a _complete_ code
The code I posted is all the code of the project. I started an empty one to
show the error.
The phrase "try to see the design of the control B" is ambiguous.
In the Solutions Explorer if make a double click in the class you see a tab
wich title is Nodo.cs[Design]. This is what I meant.

Peter Duniho said:
I just repeated the code in a new project. I did this:
1) Create a new Windows Form project.
2) Create a new UserControl called A only with this code:

public partial class A : Panel

Your post is self-contradictory. You claim to be creating a UserControl,
but the code you posted here shows you inheriting Panel instead.
[...]
3) Create a new User Control called B with this code:

public partial class B : A

Likewise, since A inherits Panel, B is also a Panel, not a UserControl.
[...]
With this code, when I try to see the design of the control B, I see an
error who says that the base class of A couldn't be loaded. I'm using VS
2008

You need to post a _complete_ code example, along with a more specific
description of what you're trying to do. The phrase "try to see the
design of the control B" is ambiguous. A class inheriting Panel can't
itself be designed at all; it can only be placed within some Form or
UserControl by the Designer. A UserControl can be designed, but your code
examples don't show you inheriting UserControl.

I have attempted to recreate the most obvious interpretation of your
posts, two different ways: with the base class inheriting UserControl, and
with it inheriting Panel. In both cases, I have no trouble at all. No
errors, no problems. Everything works just as I expect it to.

Please take more time and care with your question, to make sure that a)
the question actually makes sense rather than contradicts itself, and b)
that you have posted a code example that is both concise and complete.

Pete
 
F

Family Tree Mike

Alberto said:
I added an user control and I changed the :UserControl for :panel.

Don't do that as it is causing problems. To extend a panel, just create a
"normal" class, then set the class to extend Panel.

Mike
 
P

Peter Duniho

I added an user control and I changed the :UserControl for :panel.

As Mike says, you can't safely do that. The Designer makes certain
assumptions and inserts code specific to the class being used. If you
change the base class after the fact, it can create all sorts of problems
related to class members no longer being present. It's possible to go
hand-edit the code and fix things up, but there's no advantage in doing it
that way. Just do what Mike says: start with Control as the base class,
and specialize it to "Panel" by hand later.
You need to post a _complete_ code

The code I posted is all the code of the project. [...]

No, it's not. If it were, I'd be able to copy the code to my computer and
compile it without adding anything else.

Pete
 
A

Alberto

OK. I repeated again the example doing what you says. Here is all the code:

Class A)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public abstract class A: Label
{
string texto;

public A()
{
}

public A(string Texto)
{
this.texto = Texto;
}
}
}


Class B)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
public class B: A
{
public B()
{
}

public B(string Texto)
: base(Texto)
{
}
}
}

If you remove the "abstract" it works fine.


Peter Duniho said:
I added an user control and I changed the :UserControl for :panel.

As Mike says, you can't safely do that. The Designer makes certain
assumptions and inserts code specific to the class being used. If you
change the base class after the fact, it can create all sorts of problems
related to class members no longer being present. It's possible to go
hand-edit the code and fix things up, but there's no advantage in doing it
that way. Just do what Mike says: start with Control as the base class,
and specialize it to "Panel" by hand later.
You need to post a _complete_ code

The code I posted is all the code of the project. [...]

No, it's not. If it were, I'd be able to copy the code to my computer and
compile it without adding anything else.

Pete
 
P

Peter Duniho

[...]
If you remove the "abstract" it works fine.

Why did you add the "abstract" in the first place? That's the very first
time you've mentioned "abstract" this entire thread.

And no, you can't use a class in the Designer if you can't instantiate the
class's immediate base class with a public, parameterless constructor.
And since you can't instantiate an abstract class, your code won't work.

This is just a specific limitation of the Designer. AFAIK the only way
around it is to insert an intermediate class between the base class that
can't be instantiated and the derived class you want to use.

Pete
 
A

Alberto

I was writing some code in order to find out whats happening and take a look
at this classes:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;

namespace Análisis.UserControls
{
class Class1: Label
{
protected string a;
public Class1(string Texto)
{
a = Texto;
}
}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Análisis.UserControls
{
class Class2: Class1
{
public Class2(string Texto)
: base(Texto)
{ }
}
}

It doesn't work. It compiles right but you can't use the designer to see the
class 2. Something really strange for me.


Peter Duniho said:
[...]
If you remove the "abstract" it works fine.

Why did you add the "abstract" in the first place? That's the very first
time you've mentioned "abstract" this entire thread.

And no, you can't use a class in the Designer if you can't instantiate the
class's immediate base class with a public, parameterless constructor.
And since you can't instantiate an abstract class, your code won't work.

This is just a specific limitation of the Designer. AFAIK the only way
around it is to insert an intermediate class between the base class that
can't be instantiated and the derived class you want to use.

Pete
 
F

Family Tree Mike

Alberto said:
I was writing some code in order to find out whats happening and take a
look at this classes:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;

namespace Análisis.UserControls
{
class Class1: Label
{
protected string a;
public Class1(string Texto)
{
a = Texto;
}
}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Análisis.UserControls
{
class Class2: Class1
{
public Class2(string Texto)
: base(Texto)
{ }
}
}

It doesn't work. It compiles right but you can't use the designer to see
the class 2. Something really strange for me.

It fails for both class1 and class2 in a similar way to each other. A
class used as a component in the designer must have a parameterless
constructor. That is what the error is telling you when you try and use
these classes. It's easy to understand why. How would the designer
know to pass "Bueno" or any other string for the parameter "Texto" in
your constructor?

You will find many parts of .Net require parameterless constructors to
work. XML serialization is another place.
 
P

Peter Duniho

[...]
It doesn't work. It compiles right but you can't use the designer to see
the class 2. Something really strange for me.

As I wrote in my previous post:
[...]
And no, you can't use a class in the Designer if you can't instantiate
the class's immediate base class with a public, parameterless
constructor. And since you can't instantiate an abstract class, your
code won't work.

Your newest example fails both the test that the base class must be
instantiable via a parameterless constructor _and_ that it itself must be
instantiable via a parameterless constructor.
 

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

Similar Threads


Top