views:

46

answers:

1

I've got a flex app with a DataGrid with several columns (defined in the MXML file), and I need to "introspect" the grid columns. That is, I need to write some ActionScript code which, given the DataGrid object, can determine various things about the grid (and more specifically, the columns of the grid).

In particular, if a column is just plain text output, I don't really care about it... but if it's got "actionable" controls within it (checkboxes, linkbuttons, etc) I do.

First, I'm assuming that columns which contain "actionable" contents will be within <mx:itemRenderer> tags (else it would just be plain text); please let me know if this is incorrect.

Next I need to "dig down" into the structures, pulling the AS object corresponding to the <mx:DataGridColumn> out of the <mx:DataGrid> (I've got this), then pulling the AS object corresponding to the <mx:itemRenderer> out of the mx:DataGridColumn (two diff ways to do this; neither seems very useful), then pulling the AS object that corresponds to the <mx:Component> out of the mx:itemRenderer (if any; it's unclear to me whether the mx:Component actually creates an object), and finally pulling the AS object corresponding to the <mx:LinkButton> (or whatever) out of the mx:Component.

Does anyone know how to do this?

P.S. I understand that there's almost no limit to what could be lurking within the itemRenderer; if I can dig down that far, I'm willing to test for a handful of things that I expect and ignore the rest.


To clarify somewhat, I've been asked to provide Section 508 compliance (accessibility) to an existing application. There are a lot of pieces to this, of course, including screen readers, etc... but one of the first steps is making sure that the application can be used without a mouse.

Many of the existing screens have a UI technique consisting of a DataGrid with item renders which place controls like radio buttons and linkbuttons and whatnot into the cells (same type of control all the way down the column). All well and good, except I can find no way to interact with these controls via the keyboard.

So, I modified one screen to have a hot key which pops up a context menu, allowing the user to arrow up/down among the actionable items, and press ENTER to choose one (toggle the checkbox, press the linkbutton, etc). But this was screen-specific, and it will be too easy for someone to update the screen (e.g. adding another actionable column) and neglect the menu.

A better (?) approach was suggested: subclass the data grid, introspect to find the actionable columns, build the menu automatically, and now all we have to do is swap out the SuperDataGrid for the DataGrid, and our screens will be 508 compliant.

If someone can recommend a better way to make the screens 508-compliant (without redesigning the UI) and with minimal per-screen effort, I'm all ears.


Maybe I'm not being clear enough, since you keep missing the point, so let me try again.

I'm NOT writing application-level code... if I were, I'd know exactly what the logic is doing and I'd be able to use the bound data in the normal way. In fact, the application-level code DOES use the bound data in the normal way. But that's totally beside the point.

What I'm TRYING to do is write "infrastructure-level" code: that is, code which runs "below" the level of the application logic. I'm trying to effectively add a feature to DataGrids which Adobe should have included, but didn't. If I can get this class working, it will be possible to just drop it into dozens of screens WITHOUT ME, AS THE CLASS AUTHOR, KNOWING ANYTHING ABOUT THOSE SCREENS OR THE LOGIC WITHIN THEM. The only way I can imagine this working is to look into the datagrid and discover, at run time, what types of controls lurk within it, and possibly what they're bound to (actually, I can probably just execute whatever the click="foo()" attribute says to do, and I won't need to know what they're bound to).

Does this make sense?

Is it possible?

A: 

Item renders interact with the outside world through their data property. They should render the data as desired and make changes to data as required. They should not reach outside and you should not try to reach in to affect an item renderer directly.

As far as the underlying problem you're trying to solve, you haven't stated it at all. You're describing a desire to follow through on a particular solution only but haven't described the underlying problem. What are you really trying to accomplish? Don't talk about getting access to item renders or digging into the DataGrid, but what interaction or affect on the rows do you want? The problem is your approach is somewhat backwards and that's why it's not working out.

Sam
I don't need to affect the renderer at all, I just need to dig though the renderer to find the checkbox/etc inside, which I will affect via normal means.
MarkV
@MarkV, well, don't do that. Have the state of the checkbox reflected in the `data` the `itemRenderer` is bound to.
Sam
The state undoubtedly already is reflected in a data element... but how can I know that there *is* a checkbox, or what data element it's bound to, in a *generic* way given little but a datagrid? Finding the *existence* of the control and/or the data it's bound to is the problem, not manipulating it once I get there.
MarkV
@MarkV, if the state is reflected in the data element, then ignore just use that. You want to know if the check box is checked look at `data["checked"]` or whatever field the check box is bound to. The `data` element from the item renderer corresponds to a row in the grid's `dataProvider`.
Sam