How to override an Event in a subclassed DeskTopTextField control

As an OOP beginner I succeeded in overriding a DeskTopTextField (DTTF) control. Just by using methods with the same name and return type.

But now I want to override the TextChanged Event of an other DTTP and although I use the same kind of procedure, it ‘doesn’t work’.

What I did was just put one statement in the TextChanged Event, called TxtChanged (removed the first letter ‘e’), calling the TxtChanged-method. Then I created methods with the same name in the level above and in the main window. In the main window is the code that should be executed.
In the subclassed DTTF’s I’ve put: Self.txtChanged. Also Super.txtChanged doesn’t work

The error that I get is a StackOverflowExeption. But why?

In the override that works fine, I’ve put: Self.Text = Self.GetResult

Is the Event working differently because it starts at the lowest level? And what would be a way to solve this? It’s not a good practice (I think) to directly call the main window’s method from the TextChanged Event. Especially because an other window is also using this DTTF.

First of all, once you implement an event in a subclass, it is unavailable to any subclasses or instances. if you still want to expose the event again, what you need is called an Event Definition. You can get one that is identical to the one you implemented on the by right-clicking the event and selection Create Event Definition (it’s near the bottom).

As far as your “self” problem, you can use Self in the subclass, but when the control instance is on a window, you must use “Me” because “self” refers to the Window.

When you override a method the use of Self gets tricky based on the type of the object you’re dealing with.

Let’s say you have Class1 with a public or protected method called Test. You’ve subclassed it and made Class2 (with no method override).

In either class, calling Self.Test will call the one on Class1.

Now, if you override the method by implementing it in Class2, things get more interesting.

If the instance you’ve created is of type Class1, Self.Test calls Class1.Test. Instances of Class2 call Class2.Test and to reach up a level, you need to call Super.Test or cast the instance Class1(Self).Test if you need to be specific.

Thank you for the quick answer. In the Event I did put ‘Me’, calling it’s own method txtChanged.
But calling the method of the window doesn’t work. As a beginner, I’ve tried all combinations with ‘Me’, ‘Self’ and ‘Super’ (a bit of brute force :thinking:).
I started of course with what Xojo automatically adds:

// Calling the overridden superclass method.
Super.txtChanged()

I also tried creating an Event Definition, following this post: Avoiding the TextChanged Event in Desktop Projects – Xojo Programming Blog

But the Event Definition doesn’t show up if I want to add an Event Handler…

So, to make my situation a clearer: I have a subclass called MyDesktopTextField with a little functionality. From that subclass I made a second one called MyDesktopTextFieldDimension
This last one is on at least two windows. And I want to execute a method in the window (a different one for each window) after a TextChanged Event, without checking which window it is.

Which is why I suggested creating the event definition. You would put that functionality in the TextChanged event of the instance in each window.

Events are not the same as methods and code executed down the hierarchy, not up like overridden methods. So in your case, at each level where you want to add functionality to the TextChanged event, you need to implement the event and create a new event definition. In the event, you add your code and call RaiseEvent TextChanged. At runtime, the event is fired on the DesktopTextField first, because your MyDesktopTextField class has implemented the event, the code there runs and if you raise the event again, your MyDesktopTextFieldDimension class (if it has implemented the event) gets a shot at it… and so on down the line, right to the instances on the Windows themselves.

So, if I understand right, that means that (in my case) I have to create 12 events, one for each textfield (=instance) on a window (8 on one and 4 on the other).
If that is the case, I can directly call the appropriate method in the TextChanged Event.
Like this:
Example

Correct… and that’s the right way to do it anyway. Trying to access the methods on a window from within a class is a great way to shoot yourself in the feet later.

I also suggest that you set the scope of everything on your Window to Private and then write helper methods to access those things only if you absolutely need them. It’ll make it a lot easier to refactor later if you decide to change your interface.

1 Like

Thanks Greg!