subclass / customise WinForms controls

This forum is meant for questions and discussions about the X# language and tools
Post Reply
leighproman
Posts: 60
Joined: Tue Oct 11, 2016 8:56 pm
Location: UK

subclass / customise WinForms controls

Post 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
User avatar
Chris
Posts: 4587
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

subclass / customise WinForms controls

Post 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.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
leighproman
Posts: 60
Joined: Tue Oct 11, 2016 8:56 pm
Location: UK

subclass / customise WinForms controls

Post 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
User avatar
Chris
Posts: 4587
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

subclass / customise WinForms controls

Post 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
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
leighproman
Posts: 60
Joined: Tue Oct 11, 2016 8:56 pm
Location: UK

subclass / customise WinForms controls

Post by leighproman »

Thanks Chris - thats exactly what I was looking for - all working great now.

Leigh
FFF
Posts: 1532
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

subclass / customise WinForms controls

Post 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?
,
Regards
Karl
(on Win8.1/64, Xide32 2.19, X#2.19.0.2.)
User avatar
Chris
Posts: 4587
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

subclass / customise WinForms controls

Post 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
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
FFF
Posts: 1532
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

subclass / customise WinForms controls

Post 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...
Regards
Karl
(on Win8.1/64, Xide32 2.19, X#2.19.0.2.)
User avatar
Chris
Posts: 4587
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

subclass / customise WinForms controls

Post 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.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Post Reply