Flex - 防止拖动某些项目

时间:2010-03-22 16:19:55

标签: flex drag-and-drop

如何阻止拖动List或DataGrid的某些项?

假设我有一个包含两个项目的列表:'Tom'和'Jerry'。只有'汤姆'应该是可拖动的,而不是'杰里'。

理想情况下,我有一个'isDragEnabled(item:Object):Boolean'函数,由拖动源查询。

我的困难始于'dragStart'事件处理程序对dragSource有一个空值这一事实,所以从一开始我就很难找到拖动开始的内容。

提前致谢!

PS有关于防止或取消跌落的一些讨论,但我没有看到很多关于防止阻力开始,因此这个问题。

3 个答案:

答案 0 :(得分:3)

如果你想要的是避免拖动项目,你应该使用这样的东西:

<fx:Script>
    <![CDATA[
       private function onDragStart(event:DragEvent):void {
       var selectedNode:Object = itemsList.selectedItem;
       if (selectedNode is not a draggable item) {
           event.stopImmediatePropagation();
       }
    }
    ]]>
</fx:Script>

<s:List id="itemsList" dragStart="onDragStart(event)"/>

在拖动开始时立即调度DragStart事件,因此如果停止传播事件,则可以避免拖动项目。

答案 1 :(得分:2)

你可以做两件事:

  1. 您可以根据selectedItem的数据对象上的属性禁用列表中不可拖动的项目。这将导致它们在视觉上被禁用,您可能不需要,因此您也可以尝试...

  2. 您可以在选择有效项目(基于selectedItem的数据对象)时将列表的dragEnabled属性设置为“true”,并在项目无效时将其设置为“false”。

答案 2 :(得分:1)

好的,得到它,感谢Robusto,你的小费#2是灵感,但是我不得不使用一个鼠标聆听者 - 选择事件发生得太晚了。

在下面的示例中,我使用的是我some other question的代码。

此示例允许您仅拖动List或DataGrid中的第一项:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" minWidth="955" minHeight="600">

    <mx:List id="list" dataProvider="{['Tom','Jerry', 'Amy', 'Betty', 'Chris', 'Dean', 'Email', 'Floyd', 'Grant', 'Helen', 'Iris', 'Jack']}" minWidth="200"
        mouseDown="onMouseDown(event)"
        />

    <mx:DataGrid id="dg" dataProvider="{[{title:'Tom'},{title:'Jerry'}]}" minWidth="200"
         mouseDown="onMouseDown(event)" 
    >
        <mx:columns>
            <mx:DataGridColumn dataField="title" />
        </mx:columns>
    </mx:DataGrid>

    <mx:Script>
        <![CDATA[
            import mx.controls.listClasses.ListBase;
            import mx.events.DragEvent;


            protected function onMouseDown(event:MouseEvent):void
            {
                var listBaseComp:ListBase = ListBase(event.currentTarget);
                var clickIndex:int = this.findClickedItemIndex(event.stageX, event.stageY, listBaseComp);
                listBaseComp.dragEnabled = clickIndex == 0;
            }

            /**
             * Returns a dataProvider item that displays at the given coords for the given dataGrid.
             * Code provided by Stackoverflow user https://stackoverflow.com/users/165297/amarghosh,
             * thanks a lot!
             */
            protected function findClickedItemIndex(globalX:Number, globalY:Number, listComp:ListBase):int
            {
                var p1 : Point;
                var p2 : Point;
                var renderer : DisplayObject;

                for(var i:int=0; i<listComp.dataProvider.length; i++) {
                    renderer = DisplayObject(listComp.indexToItemRenderer(i));
                    if (!renderer) //item is not displayed (scroll to view it)
                        continue;
                    p1 = new Point(renderer.x, renderer.y);
                    p2 = new Point(renderer.width, renderer.height);
                    p1 = renderer.parent.localToGlobal(p1);
                    p2 = renderer.localToGlobal(p2);
                    if(globalX >= p1.x && globalX <= p2.x && globalY >= p1.y && globalY <= p2.y)
                        return i;
                }   
                return -1;
            }

        ]]>
    </mx:Script>
</mx:Application>