abstract, override and the Visual Studio Designer
-
Hi all, As a part of my project I have an abstract class that looks like this:
abstract class TabPageTemplate : TabPage
{
public abstract void Process();
public abstract void Cancel();
public abstract bool LoseFocus();
public abstract void Populate(int identifier);
public abstract event EventHandler PageClosed;
}I also have separate classes defined, all of which implement the above abstract class. On another
Form
(that contains aTabControl
) I can then add any of theseTabPages
and know that each one will have implemented the four methods and one event handler so I can call any of them. It works great, but there is one major inconvenience. I have to design the layout of all of thoseTabPages
in code, I cannot use the VS Designer. The reason for this is that the Designer can't create an instance of whateverTabPage
I'm busy designing (because the base class from which theTabPage
inherits isabstract
). This is the error message that the Designer gives me:The designer must create an instance of type 'MyProject.TabPageTemplate' but it cannot because the type is declared as abstract.
Would anyone have some advice for me here? At first this wasn't a problem but theseTabPages
are getting quite complex now and doing all of the control layout in code is getting very tedious. -
Hi all, As a part of my project I have an abstract class that looks like this:
abstract class TabPageTemplate : TabPage
{
public abstract void Process();
public abstract void Cancel();
public abstract bool LoseFocus();
public abstract void Populate(int identifier);
public abstract event EventHandler PageClosed;
}I also have separate classes defined, all of which implement the above abstract class. On another
Form
(that contains aTabControl
) I can then add any of theseTabPages
and know that each one will have implemented the four methods and one event handler so I can call any of them. It works great, but there is one major inconvenience. I have to design the layout of all of thoseTabPages
in code, I cannot use the VS Designer. The reason for this is that the Designer can't create an instance of whateverTabPage
I'm busy designing (because the base class from which theTabPage
inherits isabstract
). This is the error message that the Designer gives me:The designer must create an instance of type 'MyProject.TabPageTemplate' but it cannot because the type is declared as abstract.
Would anyone have some advice for me here? At first this wasn't a problem but theseTabPages
are getting quite complex now and doing all of the control layout in code is getting very tedious.I see two ways to solve the problem: 1. drop the
abstract
keyword, which obviously means you're also dropping the "must implement" protection. 2. or: use Visual Designer to design either a specialized Pamel, or a UserControl, and use code to put one of those on each of your tab pages. :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
I see two ways to solve the problem: 1. drop the
abstract
keyword, which obviously means you're also dropping the "must implement" protection. 2. or: use Visual Designer to design either a specialized Pamel, or a UserControl, and use code to put one of those on each of your tab pages. :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
Sorry Sir, But I am trying for 20 minutes to design a specialised Pamel but Visual Studio does not recognise this kind of control. I am using Visual Studio 2010. Please help! it's urgentz :laugh:
-
Hi all, As a part of my project I have an abstract class that looks like this:
abstract class TabPageTemplate : TabPage
{
public abstract void Process();
public abstract void Cancel();
public abstract bool LoseFocus();
public abstract void Populate(int identifier);
public abstract event EventHandler PageClosed;
}I also have separate classes defined, all of which implement the above abstract class. On another
Form
(that contains aTabControl
) I can then add any of theseTabPages
and know that each one will have implemented the four methods and one event handler so I can call any of them. It works great, but there is one major inconvenience. I have to design the layout of all of thoseTabPages
in code, I cannot use the VS Designer. The reason for this is that the Designer can't create an instance of whateverTabPage
I'm busy designing (because the base class from which theTabPage
inherits isabstract
). This is the error message that the Designer gives me:The designer must create an instance of type 'MyProject.TabPageTemplate' but it cannot because the type is declared as abstract.
Would anyone have some advice for me here? At first this wasn't a problem but theseTabPages
are getting quite complex now and doing all of the control layout in code is getting very tedious.I ran into that (or similar) a few years ago. Eventually I opted to use a UserControl and drop it on the TabPages. Since then I have come to the conclusion that all designing should be done on UserControls, not directly on Forms, so you can convert to Tabs if your app becomes more complex.
-
I see two ways to solve the problem: 1. drop the
abstract
keyword, which obviously means you're also dropping the "must implement" protection. 2. or: use Visual Designer to design either a specialized Pamel, or a UserControl, and use code to put one of those on each of your tab pages. :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
Thanks Luc, number 2 is what I have been doing so far but it is more tiresome than one might think - which is why I decided I need to make a plan and find a better way of doing this. I can't just drop the abstract keyword because the section of code that calls the overridden methods doesn't know which TabPage it is accessing. It does something like this:
(TabPage_First as TabPageTemplate).Process()
which means that
TabPageTemplate
must have aProcess()
method and it must be overridden byTabPage_First
(and all the other TabPages that implementTabPageTemplate
). I can however haveTabPage_First
inherit fromTabPage
as opposed toTabPageTemplate
, then open it in Designer and do what I want to do, after which I change the inheritance back toTabPageTemplate
again. It's a little bit of hassle but nothing as bad as the way I used to do it. HOWEVER, once I did that I made another unpleasant discovery. You can't use Designer to design the visual layout of controls on aTabPage
if theTabPage
isn't inside aTabControl
. All it shows is a list of all the controls on theTabPage
but not positioned on the screen as their properties dictate. You can change their properties (size, location, etc.) but it doesn't show on theTabPage
in Designer, you only see it once you compile and run the application. So here's what I ended up doing, just in case anyone else is interested; In stead of theTabPageTemplate
as described above I defined aUserControlTemplate
as follows:public abstract partial class UserControlTemplate : UserControl
{
public abstract void Process();
public abstract void Cancel();
public abstract bool LoseFocus();
public abstract void Populate(int identifier);
public abstract event EventHandler PageClosed;
}I then design various
UserControls
, all of which implement the above abstractUserControlTemplate
. At runtime I then create a new emptyTabPage
, add thisUserControl
(let's say I call itUserControl_First
) to theTabPage
, set its Dock value to Fill and then add thatTabPage
to theTabControl
. I still have to change the inheritance of theUserControl_First
fromUserControlTemplate
toUserCon
-
Sorry Sir, But I am trying for 20 minutes to design a specialised Pamel but Visual Studio does not recognise this kind of control. I am using Visual Studio 2010. Please help! it's urgentz :laugh:
public class Pamel : Panel {
// specialization code goes here
}works for me every time. PS: Feel free to choose another class name. :-D
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
I ran into that (or similar) a few years ago. Eventually I opted to use a UserControl and drop it on the TabPages. Since then I have come to the conclusion that all designing should be done on UserControls, not directly on Forms, so you can convert to Tabs if your app becomes more complex.
Thanks PIEBALDconsult. I was just typing my response to Luc when your answer came through, and it is in fact exactly what I ended up doing. I've been ignoring UserControls for too long and it seems I've now paid the price for it as I'll have to do a fair bit of work to change all my custom TabPages to custom UserControls. You live and you learn. :) I still have the problem of not being able to edit a control in Designer that implements an abstract control but I can live with that for the moment (see my response to Luc) - unless of course you know a better workaround for that?
-
Thanks Luc, number 2 is what I have been doing so far but it is more tiresome than one might think - which is why I decided I need to make a plan and find a better way of doing this. I can't just drop the abstract keyword because the section of code that calls the overridden methods doesn't know which TabPage it is accessing. It does something like this:
(TabPage_First as TabPageTemplate).Process()
which means that
TabPageTemplate
must have aProcess()
method and it must be overridden byTabPage_First
(and all the other TabPages that implementTabPageTemplate
). I can however haveTabPage_First
inherit fromTabPage
as opposed toTabPageTemplate
, then open it in Designer and do what I want to do, after which I change the inheritance back toTabPageTemplate
again. It's a little bit of hassle but nothing as bad as the way I used to do it. HOWEVER, once I did that I made another unpleasant discovery. You can't use Designer to design the visual layout of controls on aTabPage
if theTabPage
isn't inside aTabControl
. All it shows is a list of all the controls on theTabPage
but not positioned on the screen as their properties dictate. You can change their properties (size, location, etc.) but it doesn't show on theTabPage
in Designer, you only see it once you compile and run the application. So here's what I ended up doing, just in case anyone else is interested; In stead of theTabPageTemplate
as described above I defined aUserControlTemplate
as follows:public abstract partial class UserControlTemplate : UserControl
{
public abstract void Process();
public abstract void Cancel();
public abstract bool LoseFocus();
public abstract void Populate(int identifier);
public abstract event EventHandler PageClosed;
}I then design various
UserControls
, all of which implement the above abstractUserControlTemplate
. At runtime I then create a new emptyTabPage
, add thisUserControl
(let's say I call itUserControl_First
) to theTabPage
, set its Dock value to Fill and then add thatTabPage
to theTabControl
. I still have to change the inheritance of theUserControl_First
fromUserControlTemplate
toUserCon
you could consider an interface instead:
public interface IMySpecialTabPageFunctionality {
void Process();
void Cancel();
bool LoseFocus();
void Populate(int identifier);
event EventHandler PageClosed;
}then do
IMySpecialTabPageFunctionality tabPage=tabControl1.TabPages[0] as IMySpecialTabPageFunctionality;
tabPage.Process();Apply the above either to a TabPage or to a UserControl intended to be put onto a TabPage. :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
you could consider an interface instead:
public interface IMySpecialTabPageFunctionality {
void Process();
void Cancel();
bool LoseFocus();
void Populate(int identifier);
event EventHandler PageClosed;
}then do
IMySpecialTabPageFunctionality tabPage=tabControl1.TabPages[0] as IMySpecialTabPageFunctionality;
tabPage.Process();Apply the above either to a TabPage or to a UserControl intended to be put onto a TabPage. :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
Thanks Luc, When I started out doing all of this I thought that
Interfaces
would be the way to do it but I hit a snag and stopped that line of thinking. Maybe I just still don't fully understandInterfaces
. The problem I have is that anInterface
itself can't inherit from aclass
. In other words, yourIMySpecialTabPageFunctionality
interface above has the extra functions and event handlers that I want but none of the properties, methods and event handlers of aTabPage
. So if I implement that interface I have just an implementation of that interface, I don't really have an extendedTabPage
. Like I said, I have limited experience with Interfaces so maybe it's the perfect sollution. Could you clarify the issue above perhaps? -
Thanks Luc, When I started out doing all of this I thought that
Interfaces
would be the way to do it but I hit a snag and stopped that line of thinking. Maybe I just still don't fully understandInterfaces
. The problem I have is that anInterface
itself can't inherit from aclass
. In other words, yourIMySpecialTabPageFunctionality
interface above has the extra functions and event handlers that I want but none of the properties, methods and event handlers of aTabPage
. So if I implement that interface I have just an implementation of that interface, I don't really have an extendedTabPage
. Like I said, I have limited experience with Interfaces so maybe it's the perfect sollution. Could you clarify the issue above perhaps?Not sure what the problem is. In the following situation:
interface IMySpecialTabPageFunctionality {
void Process();
}class MyTabPage : TabPage, IMySpecialTabPageFunctionality {
public void Process() {
...
}
}class MyApplication {
IMySpecialTabPageFunctionality object1;
TabPage tabPage2;
MyTabPage tabPage3;
}object1 is whatever object that implements all members of IMySpecialTabPageFunctionality; it may or may not be a TabPage, so you can't just call tabpage-specific functions on it. tabPage2 is a regular tabpage, however you can't call Process() on it. tabPage3 is a specialized tabpage, offering real tabpage functionality as well as the extra interface functions. One of those is bound to offer what you want. BTW: tabPage2 and tabPage3 can be designed with Visual Designer, object1 can't. Furthermore, if you need multiple specializations with a common interface, this is what I would consider:
interface IMySpecialTabPageFunctionality {
void Process();
}class MyTabPage : TabPage, IMySpecialTabPageFunctionality {
public virtual void Process() {
...
}
}class MySpecialTabPage1 : MyTabPage {
public override void Process() {...}
}class MySpecialTabPage2 : MyTabPage {
public override void Process() {...}
}:)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
Not sure what the problem is. In the following situation:
interface IMySpecialTabPageFunctionality {
void Process();
}class MyTabPage : TabPage, IMySpecialTabPageFunctionality {
public void Process() {
...
}
}class MyApplication {
IMySpecialTabPageFunctionality object1;
TabPage tabPage2;
MyTabPage tabPage3;
}object1 is whatever object that implements all members of IMySpecialTabPageFunctionality; it may or may not be a TabPage, so you can't just call tabpage-specific functions on it. tabPage2 is a regular tabpage, however you can't call Process() on it. tabPage3 is a specialized tabpage, offering real tabpage functionality as well as the extra interface functions. One of those is bound to offer what you want. BTW: tabPage2 and tabPage3 can be designed with Visual Designer, object1 can't. Furthermore, if you need multiple specializations with a common interface, this is what I would consider:
interface IMySpecialTabPageFunctionality {
void Process();
}class MyTabPage : TabPage, IMySpecialTabPageFunctionality {
public virtual void Process() {
...
}
}class MySpecialTabPage1 : MyTabPage {
public override void Process() {...}
}class MySpecialTabPage2 : MyTabPage {
public override void Process() {...}
}:)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.