Flex: accessing child through navigating the hiererachy - apache-flex

I have a generic function to build rows of controls (each row comprising of sliders, radio buttons, reset buttons, text display) etc, and some functionality to change underlying data based on these
As I didn't want to write specific code for each row, I had code written by which I can detect the row on which there has been a mouseevent, and though the row access each individual control
The hierarchy used is titleWindow (part of popup)->skinnable container->HGroup->control
When I trace for a radiobutton, I get the path as follows Electric_Modify.TitleWindowSkin2620._TitleWindowSkin_Group1.contents.contentGroup.0.RadioButton2645
The '0' before the radioButton stands for the first Hgroup id->named as 0
I tried accessing the radio button as follows- 5th element in the HGroup
((this.contentGroup.getChildAt(row)as Group).getChildAt(4) as RadioButton).enabled=false;
and get a message "Cannot access a property or method of a null object reference" on this line. How should I navigate the hierarchy to reach the element?

You should be using getElementAt(...) and not getChildAt(...).
The get element functions represent a "higher level" element hierarchy which is needed to make skinning easier.
((this.getElementAt(row) as IVisualElementContainer).getElementAt(4) as RadioButton).enabled = false;
It should look something like that, but the exact hierarchy depends on what's in your app.

#drkstr
Thanks for your input... I thought of an alternate approach that worked for me...I mapped out the parent of the HGroup via
parent1=hgrp.parent; and then referenced these buttons as follows
((parent1.getChildAt(row)as Group).getChildAt(4) as RadioButton)
This works like a dream...I presume your suggestion would let me jump across the intermediate layers
#J_A_X/ #Constantiner: Thanks for the suggestion. I have no idea why we didn't think through and go down the DataGroup path. Prima facie seems simpler... we got to creating the UI controls in MXML laying out controls serially,and when it came to making it generic, we literally replicated the MXML approach in AS. Started off easy, till it caused problems like above. We will fix this to a better approach, when we upgrade versions. It works for now

Related

Best way to make elements non-selectable in Flex

All,
As part of requirements for a new feature of "locking" a page, it is desired to have all elements on a locked page be non-selectable. This is not to be confused with disabled. All elements should appear as if the page were active, but not be selectable.
The current thought is to create a clear canvas and place it over the existing elements. With this thought, I have two questions:
if you can think of a better way to make all items non-selectable than applying a clear canvas element over the existing elements could you describe it?
if not, what is the best way to retrofit existing implementations to accept the overlayed canvas item? BTW, all .mxml pages inherit from a custom .as file.
Sorry if this is not very descriptive, however, I am new to Flex and have spent many days trying to figure this out.
Thanks,
Todd
You could also set the mouseChildren property of the page to false so the elements will not receive any mouseEvents
All,
To fully "lock" a screen from user manipulation, one must combine Chris Bos's and www.Flextras.com's answers: disable mouse input (mouseChildren) and disable keyboard focus (focusEnabled).
Todd
Would the focusEnabled property work for you?
Documentation says it only relates to "Tabbing", but my memory says it relates to all sorts of selection.

Need to "introspect" innards of flex <mx:itemRenderer>

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?
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.

How to implement effects in Flex on components creation or removal

I have multiple MXML custom components that I add on the fly (using a repeater) that is binded to an ArrayCollection. So everytime I add/remove item from the ArrayColleciton new items show/disappear from the screen.
Is there a straightforward way to make item fade in when they get created and fade out when they are removed? I thought of using states and state transition effects but that will make things a bit complicated at different part of my application for those components to manage the states.
You need "Data effects" not "State Transitions". Creating the effect is the same, but the way you set it up is slightly different. Take a look at this list:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html?filter_flex=4.1&filter_flashplayer=10.1&filter_air=2#top
Specifically, you'll probably want to use addedEffect when something is added and removedEffect when something is removed. You may also want to investigate hideEffect and showEffect .
So, instead of creating a transitions array, you'll set the effect like it were a style in ActionScript. In MXML, set it like it were a property on the component.
And I strongly recommend not using repeaters if there is any chance your data will scroll off the screen. A repeater will renderer every element in your dataProvider. A list, will only render those elements that display on screen. Lists are much more effecient in this regards.

Flex - MATE Framework

I am new to MATE framework and I have been digging around some sample codes so that i can do the following:
On clicking a button (on a canvas)
Display a Panel.
The issue is that i am not trying to pass any value hence not sure of how/ what should be defined as sourcekey and targetkey. If this is the case, then how should one define the propertyinjector details.
most examples that are floating around contains details of reading data from a source and populating the same on a UI/ Display component.
Thanks
Srinivasan S
for this one you shouldn't use propertyInjection you should dispatch an event (you can make it custom), then you need to catch the event in the appropriate place and simply do whatever you want with it.

How do I tell Qt to always show an editor in a QTableView?

I've got a QTableView for which I want to display the last column always in edit mode. (It's a QComboBox where the user should be able to always change the value.)
I think I've seen the solution in the Qt documentation, but I can't find it anymore. Is there a simple way of doing it?
I think I could archive this effect by using openPersistentEditor() for every cell, but I'm looking for a better way. (Like specifying it only one time for the whole column.)
One way to get the automatic editing behaviour is to call the view's setEditTriggers() function with the QAbstractItemView::AllEditTriggers value.
To display the contents of a given column in a certain way, take a look at QAbstractItemView::setItemDelegateForColumn(). This will let you specify a custom delegate just for those items that need it. However, it won't automatically create an editor widget for each of them (there could in principle be thousands of them), but you could use the delegate to render each item in a way that makes it look like an editor widget.
There are two possibilities:
Using setIndexWidget, but Trolltech writes:
This function should only be used to
display static content within the
visible area corresponding to an item
of data. If you want to display custom
dynamic content or implement a custom
editor widget, subclass QItemDelegate
instead.
(And it breaks the Model/View pattern…)
Or using a delegate's paint method. But here you have to implement everything like enabled/disabled elements yourself.
The QAbstractItemModel::flags virtual function is called to test if an item is editable (see Qt::ItemIsEditable). Take a look at Making the Model Editable in the Model/View Programming documentation.
I can't see an easy way to do this, but you might be able to manage by using a delegate. I honestly don't know exactly how it would work, but you should be able to get something working if you try hard enough. If you get a proper delegate, you should be able to set it on a whole view, one cell of a view, or just a column or row.

Resources