dispatch custom event for component doesnt have parent - apache-flex

i have a Group g1 that addElement MyComponent comp1 and a UIComponent c1 add child g1
and a custom Event customEvent1 means:
c1.addChild(g1.addElement(comp1))
so comp1.parent is null
this is some code
MyComponent:
private function mouseUpFunction(e:MouseEvent):void {
//e.stopPropagation();
var event:MouseChangeEvent = new MouseChangeEvent(MouseChangeEvent.Mouse_Up_Objective);
dispatchEvent(event);
}
private function mouseDownFunction(e:MouseEvent):void{
//e.stopPropagation();
var event:MouseChangeEvent = new MouseChangeEvent(MouseChangeEvent.Mouse_Down_Objective);
dispatchEvent(event);
}
Main App:
stage.addEventListener(MouseChangeEvent.Mouse_Down_Objective, mouseDownHandler);
stage.addEventListener(MouseChangeEvent.Mouse_Up_Objective, mouseUpHandler);
the problem is comp1 dispatch the event but it never catch! :(

The "bubbles"-parameter needs to be set to true in you custom event class.

with my tests its not possible to bubble custom event in the component without parent
so you should set parent anyway

Related

how to stop getting mouse click events in flex

I have made a hierarchy in which there is a main page, using add element i have attached a component mxml of type group. There is a single button on main page when clicked it should add children of type group in that group type mxml component along with two buttons. Now using one of buttons i am attaching another component mxml type group. the problem is even they overlap i can still excess the children groups of first group component mxml. how can i stop this mouse events to happen.
I think those kind of events usually bubble up to parent components.
You can try using the following code in your mouse click event listener to stop further propagation:
private function onMouseClicked(event: MouseEvent): void {
event.stopPropagation();
... do whatever you wanted when smth was clicked ...
}
By setting enabled, mouseChildren, mouseEnabled to false, you will disable the entire component and it's children. example below
private var myPreviousGroupComponent:Group = null;
function addNewGroup():void
{
if(myPreviousGroupComponent != null)
{
myPreviousGroupComponent.enabled = false;
myPreviousGroupComponent.mouseChildren = false;
myPreviousGroupComponent.mouseEnabled = false;
}
var newGroup:Group = new Group();
addElement(newGroup);
myPreviousGroupComponent = newGroup;
}

FLEX: why the event is only listened by the dispatcher component?

I've a parent (Canvas) with many children (LinkButtons)
The linkButtons trigger an event to communicate between them:
dispatchEvent(new SameBookmarkEvent("SameBookmarkEvent", bookmark.name));
and all linkButtons have a listener
this.addEventListener("SameBookmarkEvent", highlightMe);
...
private function highlightMe(e:SameBookmarkEvent):void {
//do something
}
Now, the issue is that the event is only listened by the dispatcher child. In other words, only the child triggering the event, is receiving it. I was wondering what's wrong with it, and if I should add a listener to the parent (Canvas)...
I basically need the children (LinkButton) communicate between them
Yes, when you add the button's listener to a function within that object, of course only that object will receive the event. When you call addEventListener with the highlightMe function, you pass a reference to the highlightMe function within the current scope. That means that the private function within that class is referenced. But that function is different for each new instance of the class.
In OOP each object works for itself and doesn't know anything about the parents, so one link button should not be able to know that there are other link buttons beside itself and what those buttons do. Instead the parent knows that there are X different link buttons, each working alone, but managed by the parent to work together. In that sense, when working with events, one should always leave the event handling in the parent object – except your custom class has default handlers that keep a standard procedure working (like changing appearance on mouse over etc), or when you have custom events that encapsulate other events.
As such the correct way to deal with it, is to have a single event handler in the parent class (where you instantiate the buttons) which then also is able to identify which button the event is related to.
Example
public class SomeParent extends Sprite
{
public function SomeParent ()
{
var btn:Button;
for ( var i:uint = 0; i < 100; i++ )
{
btn = new Button();
btn.label = 'Button ' + i;
btn.addEventListener( MouseEvent.CLICK, clickHandler );
this.addChild( btn );
}
}
private function clickHandler ( event:MouseEvent ):void
{
var btn:Button = event.eventTarget as Button;
trace( 'Button with id ' + this.getChildIndex( btn ) + ' and label "' + btn.label + '" was pressed.' );
}
}

Dispatching a variable in Mate Framework

I have a grid, when i click on the edit button it goes to edit page... but i need the value in the grid also to be passed to the page.
this.dispatchEvent(new DepManagementEvent(DepManagementEvent.EDIT_NAVI));
The above code lands in EDIT page... how can i move the values too.
My Parent Page code.
private function editForm():void {
var event:DepManagementEvent = new DepManagementEvent("Edit Page",true);
dispatchEvent(event);
}
The Edit Page below....
public function init(event:DepManagementEvent):void {
this.addEventListener(DepManagementEvent.EDIT_NAVI, onEditNavi);
}
public function onEditNavi(event:DepManagementEvent):void {
Alert.show("as");
}
I am not getting the alert, when the page is navigated from the parent one.... on click. Also edit this code on how i can pass the variables too.
Add a public var (called "navi" in the code below) to the DepManagementEvent that's of the same type as the item in the grid, then dispatch the event like this instead:
var event:DepManagementEvent = new DepManagementEvent( DepManagementEvent.EDIT_NAVI );
event.navi = grid.selectedItem;
dispatchEvent( event );
To listen to the event on the other side, you add an event listener for a function...
addEventListener( DepManagementEvent.EDIT_NAVI, onEditNavi);
private function onEditNavi( event:DepManagementEvent ):void
{
// add logic here
}
Since you're in an itemRenderer, you can dispatch a bubbling event that will move up to the parent List/DataGrid and continue to bubble up to other parent views in the display hierarchy. When you create the event, pass the second argument ("bubbles") as true:
new DepManagementEvent( DepManagementEvent.EDIT_NAVI, true );

How can I trigger an itemEditEnd Event in a Flex List when the CheckBox is checked/unchecked?

I have a List component that has drop-in CheckBox itemEditor that also serves as the itemRenderer. It displays each item as a simple CheckBox with a label.
However, the itemEditEnd Event does not get triggered until I click on something outside of the List. I want it triggered once the CheckBox is checked or unchecked.
I was thinking of manually dispatching the ListEvent.ITEM_EDIT_END in a CLICK Event handler, but then the itemEditEnd Event would get dispatched twice. There's gotta be a better way to do this.
Any ideas?
Thanks.
Here is the solution I came up with. I changed my List to use the component as an itemRenderer only, not as a itemRenderer and itemEditor. I then added a MouseEvent.CLICK handler to call a function in the List from the itemRenderer to perform the necessary actions:
My List Component:
package
{
import mx.controls.List;
import mx.core.ClassFactory;
public class CustomCheckBoxList extends List
{
public function CustomCheckBoxList()
{
super();
itemRenderer = new ClassFactory(CheckBoxRenderer);
}
public function dispatchSelectionEvent(item:Object, selected:Boolean):void
{
// Take action here...
}
}
}
My ItemRenderer:
package
{
import flash.events.MouseEvent;
import mx.controls.CheckBox;
public class CheckBoxRenderer extends CheckBox
{
public function CheckBoxRenderer()
{
super();
}
override protected function clickHandler(event:MouseEvent):void
{
super.clickHandler(event);
CustomCheckBoxList(listData.owner).dispatchSelectionEvent(data, selected);
}
}
}
I've just run into this. I'm using a custom component rather than the drop-in approach, and this works when using the renderer as the editor.
Note that the Flex folks evidently came up with the notion that users would want to toggle their checkboxes a few times before settling on the state to commit to...at which point they'd hit the Enter key. How obvious!
My solution is to synthesize a keyboard event that is equivalent to hitting Enter. The tricky part is that one must use the callLater() method to dispatch the event because the list control won't have registered its keyboard listener on the editor until after the checkbox's click handler gets called. Here's my click handler for the checkbox in my custom renderer/editor component:
private function onClick(value:Object):void {
newValue = value;
var list:ListBase = ListBase(owner);
list.callLater(dispatchEvent, [new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, Keyboard.ENTER, Keyboard.ENTER)]);
}

Triggering a change event in a Flex tree control programmatically

I have a method to add an XML node structure to the currently selected tree node.
This appends the xml, and opens the parent node to display the newly added node.
I then select the node by setting the selectedItem of the tree.
I have an editing form that updates its values on the tree change event. When I set the selectedItem in this method, The node is selected correctly but the change event never fires (thus the editor doesnt update). I have tried to call it in a call later block to no avail.
Is there a way I can force the tree to dispatch a change event at this point?
public function addSelected(node:XML):void{
tree_expandItem(false);
var selectedItem:XML = tree.selectedItem as XML;
selectedItem.appendChild(node);
tree_expandItem(true);
callLater(function():void { tree.selectedItem = node; } );
}
To extend this question in a general sort of way - I would have thought that changing the selectedItem of the tree would result in a change event anyway? Or is a change only considered a change if the user makes it?
You could move the logic that is currently in your change event handler to a separate function, and then call that function directly:
private function changeHandler(event:ListEvent):void
{
doChangeLogic();
}
private function doChangeLogic():void
{
//statements
}
public function addSelected(node:XML):void
{
tree_expandItem(false);
var selectedItem:XML = tree.selectedItem as XML;
selectedItem.appendChild(node);
tree_expandItem(true);
callLater(function():void { tree.selectedItem = node; } );
doChangeLogic();
}
Is there a way I can force the tree to dispatch a change event at this point?
Use the dispatchEvent() method. Thanks James!

Resources