Custom class and UI interaction?

Hi all,

I have a window with 22 instances of a custom TextField.

When the text changes in any of them then I want to enable a PushButton.

I can’t put the code in the TextChange event of the class, and I don’t want to write it 22 times.

All solutions I can think of are extremely inelegant. How would I do this elegantly?

TIA

Markus

P.S. The only half-elegant way I can come up with is to turn my 22 TextFields into an index array, but then I loose readability in my code. It is just much easier to read

MassOfA.text = 123
MassOfC.text = 219

than

Mass(4).text = 123
Mass(18).text = 219

I’d go with the control set, but I would use constants for the index:

// Defined as constants in the window, not in code
Const MassOfA = 4
Const MassOfC = 18

Mass(MassOfA).text = 123
Mass(MassOfC).text = 219

Use AddHandler

[quote=103425:@Eli Ott]I’d go with the control set, but I would use constants for the index:

// Defined as constants in the window, not in code
Const MassOfA = 4
Const MassOfC = 18

Mass(MassOfA).text = 123
Mass(MassOfC).text = 219[/quote]
Nice idea. I might go with that. Thanks!

Never used AddHandler so am not familiar with how it works.

Wouldn’t I need to add 22 AddHandlers or can I just use an AddHandler into the class?

A simple way is to subclass TextField and make the changes in the subclass instead of the 22 instances.
I have uploaded a quick little example to my site to test and see if it fits your needs.

http://www.brumasoft.com/?p=173

Hope it helps you :slight_smile:

[quote=103430:@Amando Blasco]A simple way is to subclass TextField and make the changes in the subclass instead of the 22 instances.
I have uploaded a quick little example to my site to test and see if it fits your needs.[/quote]
Thanks.

I thought of that but then the subclass can only be used for that particular window.

The subclass is actually a NumbersOnly TextField that I use all over the place, but this is the first time I need 22 of them on one window (and that for several windows too).

Subclassing sounds like the easiest solution. What is the problem with using the subclass only on one window?

[quote=103429:@Markus Winter]Never used AddHandler so am not familiar with how it works.

Wouldn’t I need to add 22 AddHandlers or can I just use an AddHandler into the class?[/quote]

I don’t think you can add it in to the class, but you can put it in the Open event of the window control (and then just duplicate the control twenty-one more times)…

AddHandler me.TextChange, AddressOf self.TextChange

[quote=103431:@Markus Winter]Thanks.

I thought of that but then the subclass can only be used for that particular window.

The subclass is actually a NumbersOnly TextField that I use all over the place, but this is the first time I need 22 of them on one window (and that for several windows too).
[/quote]

I guess you will modify the active window textfields, so instead of hardcoding Window1, you can modify to use the activeWindow.
Also Interfaces can be handy and/or Observer OOP Pattern.

Really depends how simple you want your application. My mantra is Keep it Stupid Simple (KISS).

[quote=103431:@Markus Winter]Thanks.

(and that for several windows too).
[/quote]

I have made an untested-quick-ugly-code prototype for what you need using Interfaces. Note that the changes in 1 window now reflects on others. Made it easy to follow for you for understanding, but as I said I would not put this on my code.

There are plenty of OOP patterns that makes life easy, and in particular there is an excellent webinar about it Xojo Design Patterns by Jared that introduces to basic concepts and has an example of this what you want in particular.

You can download the new example from here.

Hope it helps you. Feel free to ask any questions

Here is the approach I would use:
Crete the subclass
Add an event definition to the subclass (I.e. mTextChanged)
In the text changed event of the subclass:

RaiseEvent mtextChanged

Now any window which contains this subclass can handle the event as it needs to, including ignoring this event if it is not needed.

[quote=103450:@Roger Clary]Here is the approach I would use:
Crete the subclass
Add an event definition to the subclass (I.e. mTextChanged)
In the text changed event of the subclass:

RaiseEvent mtextChanged

Now any window which contains this subclass can handle the event as it needs to, including ignoring this event if it is not needed.[/quote]

This works for one Window, but I he is looking for a way to display the changes among several windows. The 2nd revision of the code I posted covers this scenario.

By the way, you don’t need to add mTextChanged. Just Include the same TextChange event in the subclass and the RaiseEvent the same TextChange. You can see the code of the 1st revision I posted here.

I beg your pardon, Amando, but you are wrong on both counts.
The very reason that I would use the new event approach is that it can be handled differently by each window which contains the subclass. This is a way to let the containing window handle what happens as opposed to using the sub class’s own event as you suggest.

[quote=103452:@Roger Clary]I beg your pardon, Amando, but you are wrong on both counts.
The very reason that I would use the new event approach is that it can be handled differently by each window which contains the subclass. This is a way to let the containing window handle what happens as opposed to using the sub class’s own event as you suggest.[/quote]

You mean subclassing Window? Yeah, it works as well. As I said there are multiple ways of handling this. What I am unsure is what I have done wrongly. I instead used Interface for avoiding subclassing a Window, and adding the interface for the Windows you need this behavior, that I think works (at least on my quick prototyping tests).

[quote=103446:@Amando Blasco]I have made an untested-quick-ugly-code prototype for what you need using Interfaces. Note that the changes in 1 window now reflects on others. Made it easy to follow for you for understanding, but as I said I would not put this on my code.

There are plenty of OOP patterns that makes life easy, and in particular there is an excellent webinar about it Xojo Design Patterns by Jared that introduces to basic concepts and has an example of this what you want in particular.

You can download the new example from here.

Hope it helps you. Feel free to ask any questions[/quote]
Thanks - I actually saw the webinar, it was very good. However I did not consider an observer pattern as you usually have many observers and one subject. Here we have one observer (the save button) and many subjects.

Also a slight misunderstanding:

I enter values for the 20 amino acids and both ends of protein so in total 22 fields.

On different windows I edit different real World properties so use different classes like Hydrophobicity, Charge, Mass etc, so a Save button would need to observe the changes on its window but not those on other windows.

However I would not want to make a new subclass for each window as I often copy/paste items out of old and current projects and making it window specific will probably get me into a mess in the long run - I like my things reusable.

[quote=103450:@Roger Clary]Here is the approach I would use:
Crete the subclass
Add an event definition to the subclass (I.e. mTextChanged)
In the text changed event of the subclass:

RaiseEvent mtextChanged

Now any window which contains this subclass can handle the event as it needs to, including ignoring this event if it is not needed.[/quote]
That’s the method I started out with, but it still means pasting the RaiseEvent mtextChanged 22 times for each window … which I was trying to avoid.

Why?

A subclass of a control is just a new control. it operates as much the same and as much differently from the base control as you desire.
The subclass contains the code to limit it to numbers only (by modifiying the keydown event), if you need the textchanged event to do something different you modify the that event (all modified events can be shadowed back to be exposed as well to the parent window).

A control set allows you to manage a group of controls, and have them all react the same (or differently) to various events,
One flaw in XOJO is when you create a control set… the event header does NOT contain a reference to INDEX, but in reality it is there, and could/should be used to determine what control the event pertains to.

I have a subclass of TextEdit that by setting a custom property, can be set to only accept, TEXT, email, phone, numbers, zipcode etc. The app that uses it the most builds custom data entry screens based on a user define XML template… but the code the handles the input resides in one small place regardless of the number of controls or their location on the screen.

[quote=103460:@Markus Winter]
However I would not want to make a new subclass for each window as I often copy/paste items out of old and current projects and making it window specific will probably get me into a mess in the long run - I like my things reusable.[/quote]

You don’t need to make a subclass for the window, just add IMarkusNotifier Class Interface for the Windows you want to implement (conforms) this behavior. So in your project just add the interface for the windows that you need, and it will include an Update Method where you handle all the fields.

Patterns are not rigid, you can make your own and here we have done a different approach based on the Observer, the Markus pattern :slight_smile: