Writing own bindingsources for form controls

Posted by Kai Siegele on 17-Apr-2018 04:26

Hallo,

I have created a new ABL form-class with some textboxes on it and now I want to set some properties of the textbox depending on the values of a data object I am calling binding source.

For that purpose I have created a new class calling KontrahentBindingSource. I have added a new public string property Rating1. Than I have added the following line of code in my ABL form-class:

       tbRating:DataBindings:Add("Text", bsSpiKontrahent, "Rating1").

When compiling I got the error message parameter 2 for method is not type compatible with his definition (12905).

Has anyone an idea how to correct this error?

Kind regards

Kai Siegele

Posted by Kai Siegele on 20-Apr-2018 04:07

Hallo,

thanks all for your answers.

In the meantime I hope I have found a solution.

I have created a new class called KontrahentViewModel derived from System.Object with all of my properties I want to modify and use in my controls for example Rating1 IsValid etc. (The type of the propertiy IsValid must be character).

I have added a new object bs of type System.Windows.Forms.BindingSource to my dialog.

I have added a new object dsKontrahentViewModel of class KontrahentViewModel to the dialog.

I have added the KontrahentViewModel-object to the binding source with following line of code

       bs:Add(dsKontrahentViewModel).

I have connected the controls of the dialogs via BindSource to the properties of the KontrahentViewModel-object using following lines of code:

       tbRating:DataBindings:Add("Text", bs, "Rating1", FALSE, System.Windows.Forms.DataSourceUpdateMode:OnPropertyChanged).

...

       btnSave:DataBindings:Add("Enabled", bs, "IsValid").

and Than after connecting

Now everything seems to work as pleased. The save button is disabled until IsValid in KontrahentViewModel-object changes from “FALSE” to “TRUE” when all the ratings are correct.

Kind regards

Kai Siegele

All Replies

Posted by Laura Stern on 17-Apr-2018 05:40

Does your new class inherit from Progress.Data.BindingSource or Microsoft’s BindingSource?  It should.  A class must at least implement the IList interface to be used as a binding source.

Even if it does the column bindings are not based on public properties and if it was, .Net will know nothing about a property defined in the ABL.  There is no translation of ABL elements into the .Net world unless they are there to implement a .NET interface.  

What are you trying to do anyway?

Posted by Kai Siegele on 17-Apr-2018 07:22

Hallo Laura,

thanks for your answer.

I want to show the content of some fields in textboxes in a different way they are defined in the database. For example the field rating is an array and i want to show the content in four different textboxes. In future I want to set the foreground color depending on the value of the rating. Green = 1 and Red = 4 and so on.

For that purpose I am searching for a similar solution I am using in C#: Just defining a small class with properties for all information I want to use. Than creating a constructor with a query or table-handle to access the OE-db. Than adding information to the textbox databindings which information oft he textbox is mapped to which information of my object. And finally filling the properties from database.

Unfortunately in ABL writing a binding source is not as simple. Would you like to tell me where to find an example or a decription how to create such a binding source?

Kind regards

Kai Siegele

Posted by Laura Stern on 17-Apr-2018 09:42

Sorry, but I don't think you'll be able to do that with a BindingSource.  You'll just have to do it "manually", meaning that on some event like Form's Load, or if there is a button that move's to another record, you'd have to do it again in the button's click event, you would populate the text boxes with the values you want.

Posted by Mike Fechner on 17-Apr-2018 13:56

Did you look at using the UltraCalcManager as an alternative?

www.infragistics.com/.../wincalcmanager

Posted by jquerijero on 17-Apr-2018 14:11

Is it possible to just create a record with four similar sets of fields? Basically, explode your array.

Posted by Kai Siegele on 18-Apr-2018 03:01

Hallo Laura,

thanks for your tip, but I am affraid it solves only the fist part of my problem, displaying the content of my data object in textboxes. Second I want to react on user inputs in my dataobject and update some properties and as an reaction the state of user controls should be updated.

For example I have a form with four textboxes where I can modify the ratings of a customer and a save button. This save button should be disabled as long as the ratings are not correct. For doing this I need a way to connect controls and data object, so that data object knows when the value in control has changed and control knows when property of data object has changed.

Using C# this connection is very simple: Just add a description which property of the control corresponds to which property of my dataobject, for example:

     tbRating1.DataBindings.Add("Text", bindingSource, "Rating1", false, DataSourceUpdateMode.OnPropertyChanged);

     tbRating2.DataBindings.Add("Text", bindingSource, "Rating2", false, DataSourceUpdateMode.OnPropertyChanged);

     ...

     btnSave.DataBindings.Add("Enabled", bindingSource, "IsValid", false, DataSourceUpdateMode.OnPropertyChanged);

After writing this few lines of code everything works as pleased. That’s great, isn’t it?

Kind regards

Kai Siegele

Posted by Kai Siegele on 18-Apr-2018 06:47

Hallo Mike,

thanks for your tip, but I would prefer a solution with a strong seperation between the data object and it’s properties and calculations on the one hand and the user interface with the representation and input on the other hand. Such a solution is easy to maintain and extend when a formular must be corrected or the user input changes from a TextBox to a slider.

For connecting controls of the UI and data object, so that data object knows when the value in control has changed and control knows when property of data object has changed I need in C# only a few lines of code f.e.

     tbRating1.DataBindings.Add("Text", bindingSource, "Rating1", false, DataSourceUpdateMode.OnPropertyChanged);

     tbRating2.DataBindings.Add("Text", bindingSource, "Rating2", false, DataSourceUpdateMode.OnPropertyChanged);

     ...

     btnSave.DataBindings.Add("Enabled", bindingSource, "IsValid", false, DataSourceUpdateMode.OnPropertyChanged);

That’s great, isn’t it? And I am still searching for a similar solution in ABL. Do you have any idea?

Kind regards

Kai Siegele

Posted by Kai Siegele on 18-Apr-2018 07:11

Hallo jquerijero,

thanks for your answer.

Creating a record with four fields was exactly what I have done in first step.

Than I have created an ABL-Form with four textboxes to show and later to modify this four fields. Now I am searching for a way in ABL to connect the texboxes and the fields of the records, so that the record knows when the value in control has changed and control knows when property of data object has changed.

Using C# this connection is very simple: Just add a description which property of the control corresponds to which field of my the record (called bindingSource), for example:

    tbRating1.DataBindings.Add("Text", bindingSource, "Rating1", false, DataSourceUpdateMode.OnPropertyChanged);

    tbRating2.DataBindings.Add("Text", bindingSource, "Rating2", false, DataSourceUpdateMode.OnPropertyChanged);

    ...

After writing this few lines of code everything works as pleased. That’s great, isn’t it?

Kind regards

Kai Siegele

Posted by Laura Stern on 18-Apr-2018 07:50

Following up on jquerijero's answer, you would not do this by creating a class with public properties as you showed at first.  You would do this by defining a temp-table with the four fields, transferring the db data into there and binding the BindingSource to the temp-table buffer (not a query, just the buffer).

I'd be curious to know if this works!

Posted by Kai Siegele on 20-Apr-2018 04:07

Hallo,

thanks all for your answers.

In the meantime I hope I have found a solution.

I have created a new class called KontrahentViewModel derived from System.Object with all of my properties I want to modify and use in my controls for example Rating1 IsValid etc. (The type of the propertiy IsValid must be character).

I have added a new object bs of type System.Windows.Forms.BindingSource to my dialog.

I have added a new object dsKontrahentViewModel of class KontrahentViewModel to the dialog.

I have added the KontrahentViewModel-object to the binding source with following line of code

       bs:Add(dsKontrahentViewModel).

I have connected the controls of the dialogs via BindSource to the properties of the KontrahentViewModel-object using following lines of code:

       tbRating:DataBindings:Add("Text", bs, "Rating1", FALSE, System.Windows.Forms.DataSourceUpdateMode:OnPropertyChanged).

...

       btnSave:DataBindings:Add("Enabled", bs, "IsValid").

and Than after connecting

Now everything seems to work as pleased. The save button is disabled until IsValid in KontrahentViewModel-object changes from “FALSE” to “TRUE” when all the ratings are correct.

Kind regards

Kai Siegele

Posted by Laura Stern on 20-Apr-2018 07:08

Is KontrahentViewModel an ABL class, not .NET?  If so, can you please post this code somewhere so we can look at it.  I remember now that the Microsoft BindingSource will use reflection on a class to pick up the public properties.  But the properties need to be there.  ABL properties that are not part of a .NET interface are not put into the .NET proxy class that is emitted at runtime.  .NET knows nothing about ABL and nothing about what’s in an ABL class.  So if the class is ABL you seem to have performed a miracle.  Congratulations!


Anyway, please post if appropriate.

Thanks,
Laura



Sent from my iPad

Posted by Kai Siegele on 20-Apr-2018 08:11

Hallo Laura,

I have uploaded the file and I hope you can read it.

The class was generated using the class wizard in Eclipse. Than I have changed the base class to System.Object.

Please let me know if you need other Information.

Kind regards

Kai Siegele

Posted by jquerijero on 20-Apr-2018 09:45

By the way, OE supports pre-defining the bindingsource temp-table and fields. Just assign it later with a datasource with the same structure. This should allow you to take advantage of the UI designer when defining your individual control binding.   

[quote user="Kai Siegele"]

Hallo Mike,

thanks for your tip, but I would prefer a solution with a strong seperation between the data object and it’s properties and calculations on the one hand and the user interface with the representation and input on the other hand. Such a solution is easy to maintain and extend when a formular must be corrected or the user input changes from a TextBox to a slider.

For connecting controls of the UI and data object, so that data object knows when the value in control has changed and control knows when property of data object has changed I need in C# only a few lines of code f.e.

     tbRating1.DataBindings.Add("Text", bindingSource, "Rating1", false, DataSourceUpdateMode.OnPropertyChanged);

     tbRating2.DataBindings.Add("Text", bindingSource, "Rating2", false, DataSourceUpdateMode.OnPropertyChanged);

     ...

     btnSave.DataBindings.Add("Enabled", bindingSource, "IsValid", false, DataSourceUpdateMode.OnPropertyChanged);

That’s great, isn’t it? And I am still searching for a similar solution in ABL. Do you have any idea?

Kind regards

Kai Siegele

[/quote]

Posted by Kai Siegele on 23-Apr-2018 02:42

Hallo jquerijero,

Thanks for your tip.

I am already using the Progress.Data.BindingSource as a binding source for textboxes. Just for diplaying the information I have retrieved from temptable everything works as pleased.

But when I need to display more fields I have in the temptable f.e. a field indicating whether all inputs are ok or a color showing whether it is a good or a bad rating the solution with the Progress.Data.BindingSource is not sufficient. I think I need to create a new object for handling my additional fields and than use this new object a binding source.

Kind regards

Kai Siegele

This thread is closed