Cannot load designer view with inherited properties

Posted by jmls on 08-Nov-2012 14:22

Take this code

demo1.cls

using Progress.Lang.*.

using Progress.Windows.Form.

routine-level on error undo, throw.

class temp.demo1 inherits temp.foo:

     define private variable components as System.ComponentModel.IContainer no-undo.

     define protected variable textBox1 as System.Windows.Forms.TextBox no-undo.

     

     constructor public demo1 (  ):

          super().

          InitializeComponent().

          this-object:ComponentsCollection:ADD(this-object:components).

          catch e as Progress.Lang.Error:

               undo, throw e.

          end catch.

     end constructor.

     method private void InitializeComponent(  ):

          this-object:textBox1 = new System.Windows.Forms.TextBox().

          this-object:SuspendLayout().

          this-object:textBox1:Location = new System.Drawing.Point(149, 53).

          this-object:textBox1:Name = "textBox1".

          this-object:textBox1:Size = new System.Drawing.Size(100, 20).

          this-object:textBox1:TabIndex = 0.

          this-object:ClientSize = new System.Drawing.Size(292, 266).

          this-object:Controls:Add(this-object:textBox1).

          this-object:Name = "demo1".

          this-object:Text = "demo1".

          this-object:ResumeLayout(false).

          this-object:PerformLayout().

          catch e as Progress.Lang.Error:

               undo, throw e.

          end catch.

     end method.

     destructor public demo1 ( ):

     end destructor.

end class.

foo.cls

using Progress.Lang.*.

using Progress.Windows.Form.

routine-level on error undo, throw.

class temp.foo inherits Form:

end class.

load demo1 , view design. All is well.

move the definition of textBox1 into foo.cls

so, the code now looks like

demo1.cls

using Progress.Lang.*.

using Progress.Windows.Form.

routine-level on error undo, throw.

class temp.demo1 inherits temp.foo:

     define private variable components as System.ComponentModel.IContainer no-undo.

     

     constructor public demo1 (  ):

          super().

          InitializeComponent().

          this-object:ComponentsCollection:ADD(this-object:components).

          catch e as Progress.Lang.Error:

               undo, throw e.

          end catch.

     end constructor.

     method private void InitializeComponent(  ):

          this-object:textBox1 = new System.Windows.Forms.TextBox().

          this-object:SuspendLayout().

          this-object:textBox1:Location = new System.Drawing.Point(149, 53).

          this-object:textBox1:Name = "textBox1".

          this-object:textBox1:Size = new System.Drawing.Size(100, 20).

          this-object:textBox1:TabIndex = 0.

          this-object:ClientSize = new System.Drawing.Size(292, 266).

          this-object:Controls:Add(this-object:textBox1).

          this-object:Name = "demo1".

          this-object:Text = "demo1".

          this-object:ResumeLayout(false).

          this-object:PerformLayout().

          catch e as Progress.Lang.Error:

               undo, throw e.

          end catch.

     end method.

     destructor public demo1 ( ):

     end destructor.

end class.

foo.cls

using Progress.Lang.*.

using Progress.Windows.Form.

routine-level on error undo, throw.

class temp.foo inherits Form:

   define protected variable textBox1 as System.Windows.Forms.TextBox no-undo.

end class.

compile demo1.cls - it compiles fine, and runs fine

however, try to load into visual designer, and you get the error

"Visual Designer cannot load this class"

Line 20: Unable to locate element textBox1 in type temp.demo1

As it compiles and runs, I suspect that this is a bug in the Visual designer

comments ?

All Replies

Posted by Admin on 09-Nov-2012 00:59

jmls wrote:

"Visual Designer cannot load this class"

Line 20: Unable to locate element textBox1 in type temp.demo1

As it compiles and runs, I suspect that this is a bug in the Visual designer

comments ?

It might look like one, however the VE (or designer, huh was just looking at the namespace they use in eclipse) need to have a `model` which is `inferred` from the section it generates which is InitializeComponent.

So, it sees there is a reference to a TextBox but could not find that in it's scope... it had to give up and just throw an error

Imho, it's not a bug (sic)... you might fill an enhancement request though, that the VE scope provider to also use the inheritance chain to resolve resources. But then, when you remove that box from the canvas guess you won't expect the variable definition to be removed as well from it's parent class. Mind you, this will lead to child classes of the same form to have the same TextBox placed in different places which might be confusing (I was accused I tend to confuse peoples so you shouldn't go there as well)... is there a particular reason you don't put the TextBox on the parent form in the first place?

Posted by jmls on 09-Nov-2012 01:07

The reason why I was wanting to do this was to extract the assignment of ui values to model values out of the ui form itself.

So, I can generate foo.cls which has the ui elements defined, and the model defined, and the assignment to and from the model. The UI then inherits this class and everyone is happy.

There are a number of ways to achieve this, so I will have to look into a different one

#1 I could create a temp-table in foo, assign the buffer to and from the model, and then data-bind the ui elements to the temp-table

#2 I could create a method which takes the form and model as parameters and does the assignments. This class could then be new()ed by the form

#3 I'm sure that there are more

In the meantime I do think that this is a bug (we'll debate it next week, right?)

Posted by Admin on 09-Nov-2012 01:28

The reason why I was wanting to do this was to extract the assignment of ui values to model values out of the ui form itself.

So, I can generate foo.cls which has the ui elements defined, and the model defined, and the assignment to and from the model. The UI then inherits this class and everyone is happy.

I see, but using a Form to do 'just' the binding doesn't make it less UI isn't it?

There are a number of ways to achieve this, so I will have to look into a different one

you'll find a way, that's for sure

In the meantime I do think that this is a bug (we'll debate it next week, right?)

oh, yeah... we can have a `featherless birds` jam session @ the stadium

I'll do have a session on DSL (not LSD) and we'll talk about 'scoping'... do come, it might convince you to use a different hammer for code generation as ABL is hardly the best tool for the job

Posted by Anil Kumar on 09-Nov-2012 03:17

Hi Julian,

When you say "Extract the assignment of UI values to model  values out of the UI Form itself", do you mean extracting the code which gets  generated in 'IntializeComponent()' to display object.

Like following code for a Button.


THIS-OBJECT:button1:Location = NEW System.Drawing.Point(27,  24).
THIS-OBJECT:button1:Name = "button1".
THIS-OBJECT:button1:Size = NEW  System.Drawing.Size(75, 23).
THIS-OBJECT:button1:TabIndex =  0.
THIS-OBJECT:button1:Text =  "button1".
THIS-OBJECT:button1:UseCompatibleTextRendering =  TRUE.
THIS-OBJECT:button1:UseVisualStyleBackColor = TRUE.

Then if you  keep the following New statement also in base/super form along with variable  declarations then sub/dervived form loads properly without any error.


THIS-OBJECT:button1 = NEW  System.Windows.Forms.Button().

Hope this helps.

Thanks and Regards,

Anil Kumar.

Posted by jmls on 09-Nov-2012 03:33

not quite - I have a model class that maps properties to database records and fields, and rather than having to manually type and maintain

ui:text = model:property:text

for each property, I was hoping to generate a class automatically to manage the assignment to and from the model

This thread is closed