In the previous SmartBinding posts, I have shown how to bind to many different types of controls and data sources.
This post focus on how next kbmMW release will support binding to TImage and TListView (both the VCL and the Firemonkey variant of them).
Binding graphics to TImage and a binding catch
Binding from for example a dataset to a TImage is very easy with kbmMW, in both VCL and FMX mode. Lets make a simple example:
In the ‘Prepare dataset’ buttons event handler we have this code:
procedure TForm1.Button8Click(Sender: TObject); var mt:TkbmMemTable; csv:TkbmCSVStreamFormat; begin bnd:=nil; Binding.Clear; if dataset<>nil then FreeAndNil(dataset); csv:=TkbmCSVStreamFormat.Create(nil); try mt:=TkbmMemTable.Create(nil); mt.LoadFromFileViaFormat('biolife.csv',csv); finally csv.Free; end; dataset:=mt; bnd:=Binding.Bind(dataset,'Category',Edit5,'Text',[mwboTwoWay]); Binding.Bind(dataset,'Species Name',Edit6,'Text',[mwboTwoWay]); Binding.Bind(dataset,'Graphic',Image1,'Picture'); if bnd.Navigator<>nil then bnd.Navigator.First; end;
Basically what we do, is load a memory table with a CSV variant of biolife which also contains a bitmap. Then we bind a couple of fields to some edit boxes, and the Graphic field to the Image1.Picture property.
Running it will give this result:
And clicking the buttons will update the form according to which record is current in the dataset.
In Firemonkey, the same is possible, except you bind to the property named Bitmap of the FMX TImage
Clean and easy.
But what if we want to update the contents of the TImage, and have that reflected back in the dataset? Two way binding is the way. But there is a catch, I will explain in a moment.
First lets define the binding and make a button that loads a new image into the TImage from a file.
procedure TForm1.btnLoadBitmapClick(Sender: TObject); begin Image1.Picture.LoadFromFile('.\samplebitmap.png'); Binding.Changed(Image1,'Picture'); end;
The first line is easy to understand… it loads a PNG file based image into the TImage instance. But the 2nd line? Well.. that’s the catch.
Usually kbmMW’s SmartBinding is figuring out automatically if something has changed, and it could do so also when operating on TImage instances. However since the only way to be notified about a change in TImage, is to write an eventhandler for its OnChanged property, which could be in use by your own code, kbmMW do not really have any nice way to be notified about modifications of the image/bitmap. It could obviously continuously compare current bitmap with previously known one, as it does with other values, but since bitmaps tends to be fairly large, it would spend allot of CPU cycles doing that. Instead kbmMW SmartBind now also include features for telling it that something has been updated to let it do its magic.
Hence in this case we notify SmartBinding about that the contents of property Picture of the instance Image1 has been changed. Thus all bindings subscribing for that property needs updating and will be updated, basically resulting in the image being stored in the memory table for the current record.
SmartBinding a TListView
TListView operates slightly differently in the VCL version vs the Firemonkey version, with the Firemonkey version being much more flexible in what can be shown and how.
Binding to them are however fairly similar. List views differ from most other visual controls in that they present sub items (list items) which each of them have their own set of properties that affect the data they represent.
kbmMW SmartBind makes it easy to bind to those properties, by further extending the # syntax previously shown when binding to grids.
Let’s change the above example to now bind to a listview using the VCL.
First we add a standard TListView and bind to the list items caption and as usual its position twoway, so we can use the list view for navigation.
With its default ViewStyle (vsIcon), the application will look like this when its run.
Clicking anywhere in the list view, will automatically the position in the dataset and thus what is presented in the edit boxes.
Notice the special #caption syntax? It is one of a number of binding member names that can be used. The following table shows the currently supported ones.
In addition, you can refer to column numbers when putting the VCL TListView into ViewStyle vsReport mode, by using binding member #0..#999
The following shows that. Set the TListView’s ViewStyle property to vsReport and set its columns up:
Now bind to the column numbers 0 and 1.
Binding.Bind(dataset,'Species Name',ListView2,'#0'); Binding.Bind(dataset,'Common_Name',ListView2,'#1');
Firemonkey’s TListView do not have a report view style, but instead it has the ability to add any number of items by setting the TListView’s ItemAppearence to DynamicAppearence, and rightclick the list view instance in the designer and choose Toggle Design mode. In the next sample, I have added two text items and an image item. Notice that the names of each item is given by the TListView and can’t be altered. Hence in the example we find the list view items Text1, Image2 and Text3.
We can bind to those items very easily:
bnd:=Binding.Bind(dataset,'Common_Name',ListView2,'#Text1'); Binding.Bind(dataset,'Graphic',ListView2,'#Image2'); Binding.Bind(dataset,'Species Name',ListView2,'#Text3');
Running it will result in this:
This concludes SmartBinding #4.
As always.. if you like what you read, share the word, like us, let others know about it!