改造AdvancedDataGrid — 支持外部drag-drop

首先需要知道flex AdvancedDataGrid,DataGrid,List本身是不支持从外部拖进来一个item的(比如我想从一个List中拖进来一行,你会看到鼠标上有个红色的叉叉,表示不允许)。不过要是搞清楚一点AdvancedDataGrid内部工作原理,实现起来也不难(我可是摸索了不少时间啊,:))。

在开始之前,要先明白flex drag drop的工作原理,它的关键之处就是dragEvent,里面包含了各种各样的信息,如,action(drag/drop的类型,COPY,MOVE等),拖动的那个对象,来源对象(就是从哪里拖出来的)。最好去查查文档了解一下,非常推荐官方的devguide_flex3.pdf,里面有一章专门讲drag-drop。

进入正题,AdvancedDataGrid是如何接受drag-drop呢,关键里面有这么几个protected方法。

drag_handlers drag_handlers

 

它们就是用来处理drag-drop事件的(不止AdvancedDataGrid,还有AdvancedListBase和ListBase,以及它们的子类都可以,具体要翻看源码)。我们要做的就是改造他们 — 继承然后重写。拿drapOverHandler为例,它的源码是:

    /**
     *  @private
     */
    override protected function dragOverHandler(event:DragEvent):void
    {
        // Drag-and-drop not supported for cells
        if (isCellSelectionMode())
            return;
 
        if (!(_rootModel is IHierarchicalData) && event.dragSource.hasFormat("items"))
        {
            super.dragOverHandler(event);
            return;
        }
 
        if (event.isDefaultPrevented())
            return;
 
        if ((!_rootModel || _rootModel is IHierarchicalData) && event.dragSource.hasFormat("treeDataGridItems"))
        {
            DragManager.showFeedback(event.ctrlKey ?
                                     DragManager.COPY :
                                     DragManager.MOVE);
            showDropFeedback(event);
            return;
        }
        hideDropFeedback(event);
        DragManager.showFeedback(DragManager.NONE);
    }

很简单,它首先要检测event.dragSource.hasFormat(”items”),在我的案例里dragEvent正是包含了items,所以它被告诉要用super.dragOverHandler去处理,然后就被否定了。我们要做的就是绕过这个检测,直接执行后面的代码DragManager.showFeedback。(showFeedback是用来显示UI上的一些东西,比如显示横线表示drop的位置在哪儿等等),怎么做呢,重写dragOverHandler:

		protected override function dragOverHandler(event:DragEvent):void
		{
			if (event.isDefaultPrevented())
			{
	            return;
	  		}
 
	  		if(event.dragInitiator == this)
	  		{
	  			super.dragOverHandler(event);
	  		}
	  		else if(event.dragSource.hasFormat("items"))
	        {
		        DragManager.showFeedback(event.ctrlKey?DragManager.COPY:DragManager.MOVE);
		        showDropFeedback(event)
		    }
		    else
		    {
		    	hideDropFeedback(event);
		    	DragManager.showFeedback(DragManager.NONE);
		    }
		}

这样处理后drag-drop进来就不会看到叉叉了,正常拖入,哇哈哈。下面是我改造的dragEnterHandler:

		protected override function dragEnterHandler(event:DragEvent):void
		{
			if (event.isDefaultPrevented())
			{
	            return;
	  		}
 
	  		if(event.dragInitiator == this)
	  		{
	  			super.dragEnterHandler(event);
	  		}
	        else if(event.dragSource.hasFormat("items"))
	        { 
		        allowDragSelection = false;
		        DragManager.acceptDragDrop(this);
		        DragManager.showFeedback(event.ctrlKey?DragManager.COPY:DragManager.MOVE);
		        showDropFeedback(event)
		        return;
		    }
		    else
		    {
		    	hideDropFeedback(event);
		    	DragManager.showFeedback(DragManager.NONE);
		    }
 
		}

是不是很简单?你需要结合源码来看。除了它们,还有一个非常关键的drapDropHandler,它是用来处理drop之后的操作,这个改写要复杂许多了,这里暂不公开,以后有空写。

 

 

原文:http://gain-loss.org/?p=339

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值