Flex - предотвратить перетаскивание для определенных предметов - PullRequest
2 голосов
/ 22 марта 2010

как бы вы предотвратили перетаскивание для некоторых элементов вашего Списка или DataGrid?

Допустим, у меня был список с двумя пунктами: «Том» и «Джерри». Только «Том» должен быть перетаскиваемым, а не «Джерри».

В идеале у меня была функция isDragEnabled (item: Object): Boolean, которая запрашивается источником перетаскивания.

Мои трудности начинаются с того факта, что обработчик события dragStart имеет нулевое значение для dragSource, поэтому с самого начала мне трудно понять, что такое drag-start ..

Заранее спасибо!

PS Было несколько обсуждений о предотвращении или отмене отбрасывания, но я мало что видел о предотвращении начала перетаскивания, отсюда и этот вопрос.

Ответы [ 3 ]

3 голосов
/ 22 сентября 2011

Если вы хотите избежать перетаскивания элемента, вы должны использовать что-то вроде этого:

<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 отправляется сразу после начала перетаскивания, поэтому, если вы остановите распространение события, вы предотвратите перетаскивание элемента.

2 голосов
/ 22 марта 2010

Вы можете сделать две вещи:

  1. Вы можете отключить элементов в Списке, которые нельзя перетаскивать, основываясь на свойстве объекта данных selectedItem.Это приведет к тому, что они будут отображаться визуально отключенными, чего вы, возможно, не хотите, поэтому вы также можете попробовать ...

  2. Вы можете установить свойство dragEnabled списка в значение "true", если оно действительноэлементы (основанные на объекте данных selectedItem) выбраны и имеют значение «false», если элементы недействительны.

1 голос
/ 23 марта 2010

Ладно, понял, спасибо, Робусто, ваш совет №2 был источником вдохновения, однако мне пришлось использовать слушатель с мышью вниз - событие выбора срабатывает слишком поздно.

В приведенном ниже примере я использую код из некоторого другого вопроса моего.

Этот образец позволяет перетаскивать только первый элемент в списке или в 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...