TEPPEI STUDIO

ENJOY RESTRICTION

selectedIndexが変化しているのにchangeイベントが発行されない

DataGridのmx.events.ListEvent.CHANGE イベントですが、selectedIndexが変化しても、発行されないパターンがあるので要注意です。
具体的には以下の2パターンです。

  • いずれかの行の上でMouseDownを行い、そこでMouseUpせずに、DataGridからMouseOutして、そこでMouseUp。この場合Changeイベントが発行されませんが、MouseDownの時点でselectedIndexは変化しています。
  • いずれかの行が選択されている状態で、その行の上でCtrlキー押下しながら、MouseDownすると、selectedIndex=-1に変化するのに、Changeイベントは発行されません。

DataGridでレコードが選択されたことを契機に何かの処理を実装する場合には、DataGridのChangeイベントを契機とする実装が一般的だと思いますが、上記の点に注意しなければなりません。
最大公約的にはMouseDownを拾うしかないのですが、それだと、データが存在しない行を叩いても発行されてしまうし、何よりselectedIndexが変化する契機を拾うことができません。DataGridを拡張して、MouseDownイベント時に、バックアップにとっておいたSelectedIndexと、今のSelectedIndexを比較して、代わってるならChangeイベントを発行するという実装を加えないとダメですね。

以下、上記事象を検証したアプリです。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="vertical" applicationComplete="initApp()">

<mx:Script>
	<![CDATA[
		import mx.events.ListEvent;
		
		private function initApp():void
		{
			var t:Timer = new Timer(100);
			t.addEventListener(TimerEvent.TIMER, timerHandler);
			t.start();
		}
		
		private function timerHandler(e:TimerEvent):void
		{
			this.sitxi.text = dg.selectedIndex.toString();
		}
		
		private function dgEvent(e:Event):void
		{
			this.txa.text = e.type + "\n" + this.txa.text;
		}
			
	]]>
</mx:Script>

<mx:ArrayCollection id="ac">
	<mx:Object a="A1" b="B1" c="C1"/>
	<mx:Object a="A2" b="B2" c="C2"/>
	<mx:Object a="A3" b="B3" c="C3"/>
	<mx:Object a="A4" b="B4" c="C4"/>
</mx:ArrayCollection>

<mx:HBox>
	<mx:DataGrid id="dg" 
		dataProvider="{ac}" 
		change="dgEvent(event)" 
		click="dgEvent(event)" 
		itemClick="dgEvent(event)" 
		mouseDown="dgEvent(event)" >
		<mx:columns>
			<mx:DataGridColumn dataField="a" headerText="A"/>
			<mx:DataGridColumn dataField="b" headerText="B"/>
			<mx:DataGridColumn dataField="c" headerText="C"/>
		</mx:columns>
	</mx:DataGrid>
		
	<mx:TextArea id="txa" width="200" height="{dg.height}"/>
</mx:HBox>

<mx:Form>
	<mx:FormItem label="selectedIndex">
		<mx:TextInput id="sitxi"/>
	</mx:FormItem>
</mx:Form>


</mx:Application>