InitializeComponent

Posted by GregHiggins on 14-Jan-2009 10:36

I've given this some thought and I thought I'd throw this out for discussion.

Currently all event subscriptions are in InitializeComponent associated with the specific object.

I'm wondering how difficult it would be to centralized these subscriptions in a eventSubscriptions method (if necessary called from InitializeComponent). This would make it easier to adjust modify subscriptions without messing with the InitializeComponent code.

All Replies

Posted by rbf on 15-Jan-2009 01:43

Sounds like a good idea to me.

The subscription code is one of the few things you need to modify from time to time in initializeComponent, which should be left alone otherwise.

It would also make the subscription code much more readable, and you could leave the initializeComponent code hidden most of the time.

Posted by Admin on 15-Jan-2009 02:06

I'd consider that in the context of partial classes as used by the Microsoft Visual Studio.

I usually create a class ThisIsMyFormDesigner.cls in the Visual Designer. Then I create another class inheriting from that class (names ThisIsMyForm.cls). This class is supposed to contain "my" code - separated from the generated code.

In C# you'd have a ThisIsMyForm.Desinger.cs and a ThisIsMyForm.cs. Both files will get compiler into a single class.

Using inheritance is a structural difference to the usage of partial classes, but IMHO as close as we can get with OO in the ABL today.

I need to mark all controls that require event as protected (Family in the Visual Designer) or use THIS-OBJECT:Controls to get the reference. I usually code the Subscribe code and event handler block manually (pasted from the class browser). It's a little added work, but then I usually have better control over the code. I have the feeling, that from a maintainably point of view this works better than having a single file. It also helps with merging changes by an SCM tool, because you can look at changes in the custom code separated from changes in the Visual Design file.

Posted by rbf on 15-Jan-2009 02:15

Can you explain this in plain english in OE(A) terms (perhaps with an example)?

Posted by Admin on 15-Jan-2009 02:23

Ok. Give some time. I'll post something during the day.

Posted by GregHiggins on 15-Jan-2009 07:50

Think of it as the separation of UI layout and UI logic.

Create the visual form in my/object/path/forms/design/myApplicationForm.cls .

This has only the components with none of the event code, no processing or initialization code of any kind, except the properties necessary to set the unchanging features of the form.

Then, you define a new object:

class my.object.path.forms.myApplicationForm inherits my.object.path.forms.design.myApplicationForm ...

All of the event-code, non-visual-designer initialization code, local methods, etc goes in this new object.

This way the UI inherits the UI layout.

I'm not sure it's a best practice, but it is an interesting idea worth exploration. At the very least, it removes the 10 ton gorilla procedure from the ui logic development form.

Posted by rbf on 15-Jan-2009 07:54

>Think of it as the separation of UI layout and UI logic.

Now I understand!

If you put it that way, yes, that would certainly be the way to go.

I will experiment with this approach right away.

If it's not best practice, does anyone have an idea for even better practice?

Posted by Admin on 15-Jan-2009 07:57

This is a nice idea.

In a quick test though, unless I'm doing something incorrectly, it seems the AutoCompletion within the second class does not see controls (properly set as Protected) that have been added to the Designer class.

Posted by Admin on 15-Jan-2009 07:58

Hi Peter, attached is my sample.

Actually there are two ways to get to the references (= Handles) of the Controls in the inheriting class:

1. marking them public or protected in the Visual Designer. That's modifier property of each Control (Family = Protected).

2. Use THIS-OBJECT:Controls

This first is strong typed. But requires to mark Controls protected or public.

The second is weak typed - all items are a System.Windows.Forms.Controls and need to be casted to a specialiced type if you need to access properties and methods that are not available on the SWF.Control.

The sample has 4 events.

First a simple hello world button. And the other 3 events allow you to drag & drop the listviewitem from left to right.

Place them in a folder Consultingwerk\Samples\PartialClass

The only better way, I can think of would be real partial classes. Where this get's compiled into the same .r file.

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/SamplePartialForm.cls:550:0]

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/SamplePartialFormDesigner.cls:550:0]

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/SamplePartialFormDesigner.resx:550:0]

Posted by Admin on 15-Jan-2009 08:00

Works for me when you start with THIS-OBJECT and a colon

Posted by Admin on 15-Jan-2009 08:07

If you want to avoid that someone (you or OEA) launches the Design part directly, something like this in the Constructor helps:

But waiting for the next beta program and ask for virtual classes might be another option

Posted by Admin on 15-Jan-2009 08:20

It started working after performing a clean on the project.

Thanks.

Posted by GregHiggins on 15-Jan-2009 09:11

I'm still experimenting with a conglomerate of reusuable user controls instead of a single form with multiple individual controls.

The issue with an inherited layout is reusability and changes, the issue with conglomerates of user controls is inter-control communication. It's still early yet to be promoting a specific best practice.

Posted by rbf on 16-Jan-2009 09:01

Thanks a lot for the example Mike, now I understand what you were saying!

This looks like an interesting approach indeed. I have started experimenting with it.

Posted by Admin on 16-Jan-2009 09:04

ABL source code is the best common language fore developers .

You're welcome!

Posted by rbf on 22-Jan-2009 05:57

If you want to avoid that someone (you or OEA)

launches the Design part directly, something like

this in the Constructor helps:

IF THIS-OBJECT:GetClass():TypeName =

"Consultingwerk.Samples.PartialClass.SamplePartialFor

Designer" THEN DO:

MESSAGE "Class

Consultingwerk.Samples.PartialClass.SamplePartialForm

esigner is virtual and shall not be used directly."

VIEW-AS ALERT-BOX.

, THROW NEW AppError ("Class

Consultingwerk.Samples.PartialClass.SamplePartialFormD

esigner is virtual and shall not be used directly.")

.

END.

But waiting for the next beta program and ask for

virtual classes might be another option

It is possible to make the code generic (by adopting a naming convention), but have you found a way to achieve this in a generic super class?

Posted by rbf on 14-Feb-2009 07:14

I just ran into something really strange: when I create a new form in my 'dotnet' package named 'mainmenuform' and run it OE generates the following error message:

"The rcode does not match the package name. Rcode has package dotnet.mainmenuform, but expected mainmenuform (12877).

Could not find class or interface mainmenumform. (12886)."

If I name the class 'mainmenu' or 'mainmenufrm' it works fine.

The difference turns out to be that the statement 'USING "dotnet.mainmenufrm" FROM PROPATH.' is not generated when I name the class mainmenuform.

Is this a bug, a naming convention or am I missing something?

Posted by Matt Baker on 14-Feb-2009 07:36

You probably don't have your propath setup properly. And you don't want a using statement pointing to the same class that you are in.

Posted by rbf on 14-Feb-2009 08:08

You probably don't have your propath setup properly.

And you don't want a using statement pointing to the

same class that you are in.

1. That does not explain that 'mainmenu' or 'mainmenufrm' work fine.

2. I am not generating that statement, it is generated by OEA when you run a class

Posted by Matt Baker on 14-Feb-2009 14:37

Ok, I read the error message again. Did you move the form, or rename it? It seems to not only be referenced by a different package name, but there is an extra 'm' in the 12886 error message reference .

dotnet.mainmenuform

mainmenumform

Posted by Matt Baker on 14-Feb-2009 14:40

Other possibility is that you have two classes with the same name in two different packages?

Posted by rbf on 15-Feb-2009 10:43

Yes I did move the form and renamed everything appropriately (I think).

The extra 'm' was a typo to this forum, it is not in the error message.

I am still struggling with this. I have two forms:

CLASS dotnet.mainmenuform INHERITS Form:

and

CLASS dotnet.mainmenu INHERITS dotnet.mainmenuform:

Everything compiles and works fine if I start it like this:

DEF VAR omainmenu AS dotnet.mainmenu NO-UNDO.

omainmenu = NEW dotnet.mainmenu().

WAIT-FOR System.Windows.Forms.Application:Run(omainmenu).

But when I try to run mainmenu.cls from OEA I get the message that the rcode does not match the package name. It has package name 'dotnet.mainmenu' but expected 'mainmenu'.

Yes, the problem now shifted to mainmenu.cls from mainmenuform.cls. I can get it back by playing around with the 'dotnet' prefixes...

Posted by Admin on 15-Feb-2009 10:59

Are you using a different propath in your run configuration?

An old R-Code somewhere? (from a move or rename operation)

Posted by rbf on 15-Feb-2009 11:42

Are you using a different propath in your run configuration?

No. I also deleted all old run configurations.

An old R-Code somewhere? (from a move or rename operation

Nope.

This thread is closed