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 ?
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?
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?)
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
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.
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