This is the 4th video and blog in a series on using Visual LiveBindings mixed into existing VCL applications.
In my last post, we looked at how to bind directly in code, using some common Visual LiveBinding Classes and in the next post we will look at more classes that can be used and the difference in the bindings they create. However before we get there a number of you asked about binding to master detail and sub objects. So lets explore this matter.
More in the blog post.
Master detail and Visual Live Bindings
Master detail relationships (in database programming) are where one record has a number of linked records. e.g. Every Customer may have a list of multiple Orders.
TDataSet with Master Detail
When working with TDatasets, parameters have been used to filter the detail based on the selected record. Working with LiveBindings and TDataSet and when data is kept in sync, this approach still works. The challenge arises when working with objects. How do you keep the instance of a class (object) in sync with the detail?
Objects and Classes with Master Detail
When using LiveBindings with an object (an instance of a class) and you have additional objects that are properties of the class, or when you have a separate list that you want to filter based on the master object, we have to do a little work to make the LiveBindings work.
(Code sample below)
Example of MasterDetail in an object.
The following is an example of a master detail relationship as far as Visual LiveBindings is concerned using an object, TFoo that contains a TFoo2. (I’ve compacted the declarations a little for illustration from the sample)
TFoo2 = class private F2V: string; public property Foo2Value: string read F2V write F2V; end; TFoo = class private FName: string; FV: Integer; FFoo2: TFoo2; public property Name : string read FName write FName; property Value : Integer read FV write FV; property Foo2 : TFoo2 read FFoo2; end;
The above shows a TFoo class (master) that has a property that is a TFoo2 (detail). While you can bind to Foo.Name, unfortunately, you can’t bind to Foo.Foo2.Foo2Value directly so we need to link a second data source to the detail object.
Thinking about transitional database development, you have two data sets (master and detail), so in comparison here, you can use two ProtoTypeBindSource to link to Foo (master) and Foo2 (detail)
As this post expands from the last post where Visual live bindings via code I will not repeat what we already know here, but I will expand to show you the properties for linking a new edit control to the new property. In short, its the same, but take note, the DataSource is the new ProtoTypeBindSource
LinkControl := TLinkControlToField.Create(Self);
LinkControl.DataSource := pbsFooFoo2Object;
LinkControl.FieldName := 'Foo2Value';
LinkControl.Control := Edit2;
LinkControl.Track := True;
Keeping LiveBindings detail up to date.
Now you have the binding created, its time to look at how to keep the detail updated every time the master is changed.
In short, the BindSourceAdapter that is created for the Master has an AfterScroll property, use this event to update the object linked to in the BindSourceAdapter linked to the detail. (see video)
Additionally, The detail BindSource Adapter uses the BeforeScroll event to check the state of the current binding. If data has been changed, it posts the changes before scrolling.
Now this can be arduous and create a bit of code on the form to manage, so to make life easier, I have created (using Generics) a helper class that creates the BindSourceAdapters required and the events for the AfterScroll and BeforeScroll appropriately. Using Anonymous methods it them allows you to easy define how to get to the detail when given the master object. (available in the link below).
Visual Live Bindings Example Code
The source code for this video and blog post is available on Code Central http://cc.embarcadero.com/item/30438
Hope this gets you going with using Master detail with objects. I may look to update the example in the future to work with multiple objects, but for now…. unless someone wants to submit back to me their own example based on this blog to share.
Happy coding!
(sorry my english) It’s Great Arcticle! But i need to know if it’s possible bind a foo.foo2.foo2value without a lookup or without use other prototypebindsource for work?
You will need to bind to the other classes in a different prototype bind source as they work with a single instance / list. Please also read and watch the follow on blog posts where I explore this further.
https://delphiaball.co.uk/2015/11/26/livebindings-in-vcl-part-5-advanced-master-detail-objects/ and https://delphiaball.co.uk/2015/11/27/livebindings-in-vcl-part-6-master-object-detail-tdataset/