This is a question about data binding to a custom class while using custom item renderers. I'm pretty new to flex so I'm not exactly sure how data binding works internally.
I created a custom class (Headache) as part of my data model. I am using an editable DataGrid to view / set the properties of the Headache, and this seemed to work (even before I put the [Bindable] tag in front of my Headache class, which kind of mystified me). But then when I set a column of the DataGrid to an custom item renderer (NullableDateDisplay, which I created in mxml), I got this warning:
warning: unable to bind to property 'unpleasantness' on class 'model::Headache'
The data shows up, but now when I click to try to edit the property in the DataGrid, it displays like this:
[object Headache]
And when I try and set the value, I get this:
[Fault] exception, information=ReferenceError: Error #1069: Property text not found on components.NullableDateDisplay and there is no default value.
You have to make use of data method when implementing custom renderer
override public function set data(value:Object):void {
super.date = value;
var headacheModel:HeadacheModel = value as HeadacheModel;
if(!headacheModel) {
return;
}
textAreaUI.text = data.tag;
}
You need to set the editorDataField on the DataGridColumn to whatever field will hold the edited value in the renderer instance. If your item editor does not inherit an actual control (like say a NummericStepper), then you can create a public property on the renderer and store the edited value there.
Since you are using a custom ItemRenderer, it would definitely be great to override the "data" setter as venkatsnet pointed out ( personally, I wouldn't apply the values to my controls, right inside the setter... instead, you should define a "dataChanged" flag and set the values in the commitProperties() method - in case you are not familiar with this, then set things directly in the setter, but definitely read up on commitProperties, measure and updateDisplayList at a future point in time ).
I'm guessing that you are trying to access the "unpleasantness" property inside your custom item renderer... you could avoid using binding completely if you fill your controls manually ( I seriously doubt you need binding anyway, just that you don't really know there are other approaches to your problem as well ), like in venkatsnet's reply ( textAreaUI.text = data.tag; ).
Also: posting the actual code of Headache and your custom item renderer, is always welcome ( or event better: post the project so we can run it; or at least try to reproduce the problem in a new project and upload that one instead )... explaining what you did is Ok, but your explanations might be misleading or might not contain the needed information to point out the exact cause of the problem ( just like in this case... we have no idea how your code actually looks like and just a really brief description about what you did, won't really cut it ).
__________________ Titus M. Plautus - Not by age but by capacity is wisdom acquired.
Last edited by Barna Biro; 07-01-2011 at 04:24 PM.
I threw together 2 fast examples that will hopefully get you on track. One that doesn't use binding ( and makes use of the commitProperties() approach I have previously mentioned ) and one that uses binding. Since you didn't mention the Flex version you are using, I went with the 4.5.1 SDK, but things would have been done the same way in older versions as well.
__________________ Titus M. Plautus - Not by age but by capacity is wisdom acquired.
Last edited by Barna Biro; 07-02-2011 at 01:21 AM.
Barna Biro, you're right, I didn't explain my problem clearly enough. Actually, I was having one problem (not implementing the set data function) that was obscuring my other problem! I want to be able to update the model through the DataGrid, that's why I was using data binding. Before I started using a custom itemRenderer / editor, when I edited a value in the datagrid, the model would automatically update, and that isn't happening now. I know that I could manually update the model, but I don't understand why databinding stopped working when I started using a custom itemRenderer.
I've attached my code if anyone wants to take a look at it.
There's no way for your data to update automatically with your current code. The model was being updated before you started using a custom item renderer, most likely because the grid was using the entire model object directly ( knowing, by default, how to render only the specified dateField value and then update the model if the value changes ). When using a custom item renderer, you are kinda responsible for making any updates or whatever might be required explicitly / manually...
In order for you model to update, you have to handler the changing of the DateField value and apply the selected value to the model explicitly.
Also, normally, you don't really want for you model to automatically update ( not once, you will need to make some checks and make sure that certain conditions are met, before actually applying the new value ).
__________________ Titus M. Plautus - Not by age but by capacity is wisdom acquired.
Last edited by Barna Biro; 07-06-2011 at 12:27 PM.
Data binding links a data layer with graphical controls and enables data independency of its presentation. Data binding is broadly used in WinForms applications, while in WPF applications it is practically the only data presentation method. Correct organization of data binding is the foundation of well-built applications.
Code:
//Build a header with columns
grid.Headers.Add(new Header());
grid.Headers[0].Add(new Column("IntValue"));
grid.Headers[0].Add(new Column("DoubleValue"));
grid.Headers[0].Add(new Column("StringValue"));
//Add data object at the top-level and attach 2 children of the same type
Row row1 = grid.Rows.Add(new MyCustomClass(10, 11.11, "item 1"));
row1.Add(new MyCustomClass(11, 11.22, "subitem 1"));
row1.Add(new MyCustomClass(12, 11.22, "subitem 2"));
//Add data other data object with 2 children
Row row2 = grid.Rows.Add(new MyCustomClass(20, 22.11, "item 2"));
row2.Add(new MyCustomClass(22, 22.22, "subitem 1"));
row2.Add(new MyCustomClass(22, 22.22, "subitem 2"));
you can find this tutorial here
dapfor. com/en/net-suite/net-grid/tutorial/data-binding