Page 1 of 1
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 1:20 pm
by leighproman
Is there an example somewhere of how to customise/subclass a control type for Windows Forms?
For VO forms I have a custom TextBox class which I set the background colour on focus/lose focus.
I want to do the same thing in Windows Forms without having an event for every control but can't work it out.
Thanks
Leigh
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 1:36 pm
by Chris
Hi Leigh,
You just need to declare a custom class that inherits from TextBox and add all your custom code there. Better add this class in a base library and then, after you build it, that "new" control should appear in the Toolbox.
In order to convert previous TextBox controls to the new one, you need to go to the designer generated code and change the class names, from the old one to the new one. That needs to be done in 2 places, in the class declaration of the form where the control iVars are declared, and inside the constructor, in the beginning of it, where they are being instantiated.
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 3:34 pm
by leighproman
OK so I've created new library with this class:
Code: Select all
PUBLIC CLASS LeighTextBox INHERIT System.Windows.Forms.TextBox
CONSTRUCTOR() STRICT
RETURN
PRIVATE METHOD Enter(sender AS OBJECT, e AS System.EventArgs) AS VOID STRICT
SELF:BackColor := System.Drawing.Color.Yellow
RETURN
PRIVATE METHOD Leave(sender AS OBJECT, e AS System.EventArgs) AS VOID STRICT
SELF:BackColor := System.Drawing.Color.White
RETURN
END CLASS
I've added the DLL as a reference in my project and changed the class name in the 'form.designer' code and it all builds ok.
Unfortunately the modified control doesn't change colour as hoped!
Anything obvious that I'm missing?
Thanks
Leigh
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 5:39 pm
by Chris
Hi Leigh,
If you do not want to use events (like Enter += myhandler), you need to override the On* methods. In this case:
PROTECTED OVERRIDE METHOD OnEnter(e AS EventArgs) AS VOID
SUPER:OnEnter(e)
// .. add your code here
RETURN
(note that the "OVERRIDE" keyword is not strictly necessary, if you have the /vo (all methods VIRTUAL) compiler option enabled.
You can view the correct parameters for the On() methods in the .net docs (they are the same as their respective event handler methods, but without the first OBJECT param):
https://docs.microsoft.com/en-us/dotnet ... work-4.7.1
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 6:23 pm
by leighproman
Thanks Chris - thats exactly what I was looking for - all working great now.
Leigh
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 7:39 pm
by FFF
Chris wrote:If you do not want to use events (like Enter += myhandler), you need to override the On* methods. In this case:
...
pmfji, followed and learned, thx.
Is it correct, that the
Code: Select all
...
SELF:oTextBox1:Enter += SELF:TextBox1Enter
...
METHOD TextBox1Enter(sender AS System.Object , e AS System.EventArgs) AS VOID
SELF:oTextBox1:BackColor :=System.Drawing.Color.Yellow
RETURN
version binds the handling to the form - i.e., everytime i want a LeighSLE on a form i have a copy of this code in the form's source, so only the OnEnter encapsulates my behaviour into the control?
,
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 8:20 pm
by Chris
You're welcome Leigh!
Karl, yes, typically you would always use the event because it is an easy way to do this without subclassing, but when you use a subclass, you can either use the On? methods, or can still use an event, handled at the subclass level.
Btw, the same behavior can be achieved also without subclassing, you could write some code that gets executed after the form is generated and manually bind to the events. Something like this:
Code: Select all
METHOD BindEvents(oForm AS Form) AS VOID
FOREACH oControl AS Control IN oForm:Controls
IF oControl IS TextBox
oControl:Enter += myEnterHandler
END IF
NEXT
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 8:37 pm
by FFF
Chris wrote:Karl, yes, typically you would always use the event because it is an easy way to do this without subclassing, but when you use a subclass, you can either use the On? methods, or can still use an event, handled at the subclass level.
Btw, the same behavior can be achieved also without subclassing, you could write some code that gets executed after the form is generated and manually bind to the events. Something like this:
Code: Select all
METHOD BindEvents(oForm AS Form) AS VOID
FOREACH oControl AS Control IN oForm:Controls
IF oControl IS TextBox
oControl:Enter += myEnterHandler
END IF
NEXT
Argh, that's too much for my rusty brain...
Your BindEvents belongs to which class? The shell? myEnterHandler is a method of ...?
BTW, don't unterstand why folks shy of subclassing. Only to think of the pain folks experienced, fiddling with generated code in "painted" forms, VS denying to open the form etc...
subclass / customise WinForms controls
Posted: Tue Jun 02, 2020 8:40 pm
by Chris
Hi Karl,
Most suitable it is to define it in the same class with the form. Not using subclassing is just simpler...but if there's no other convenient way to do what you want, subclassing is also fine.