Actionscript 3 防止Flex树丢弃反馈
我希望允许用户在Flex树文件夹中重新排序项目,但不将这些项目移到文件夹外。我可以阻止外部掉电成功,但我想(在掉电之前)给用户反馈掉电不会成功。我已经找到了很多关于删除操作的例子,但是没有任何东西能够向用户显示正确的反馈 根据树文档,我应该能够在Actionscript 3 防止Flex树丢弃反馈,actionscript-3,apache-flex,drag-and-drop,Actionscript 3,Apache Flex,Drag And Drop,我希望允许用户在Flex树文件夹中重新排序项目,但不将这些项目移到文件夹外。我可以阻止外部掉电成功,但我想(在掉电之前)给用户反馈掉电不会成功。我已经找到了很多关于删除操作的例子,但是没有任何东西能够向用户显示正确的反馈 根据树文档,我应该能够在dragOver事件期间调用DragManager.showFeedback(DragManager.NONE),但这不起作用。下面是一个简短的示例项目。是否有任何方法可以在拖动事件期间向用户指示拖放不会成功 提前感谢您提供的任何解决方案 <?xm
dragOver
事件期间调用DragManager.showFeedback(DragManager.NONE)
,但这不起作用。下面是一个简短的示例项目。是否有任何方法可以在拖动事件期间向用户指示拖放不会成功
提前感谢您提供的任何解决方案
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="354"
height="480">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.core.IUIComponent;
import mx.core.mx_internal;
import mx.events.DragEvent;
import mx.events.FlexEvent;
import mx.managers.DragManager;
protected function tree_dragEnterHandler(event:DragEvent):void {
// only items can be dragged - not folders
if (tree.selectedItem.@type == "item") {
DragManager.acceptDragDrop(IUIComponent(event.currentTarget));
} else {
event.preventDefault();
DragManager.showFeedback(DragManager.NONE);
}
}
protected function tree_dragOverHandler(event:DragEvent):void {
var dropData:Object = tree.mx_internal::_dropData;
var dragItem:XML = event.dragSource.dataForFormat("treeItems")[0];
if (!dropData || !dropData.parent || !dragItem.parent() || dragItem.parent() != dropData.parent) {
trace("preventing drop");
DragManager.showFeedback(DragManager.NONE);
return;
}
trace("allowing drop");
DragManager.showFeedback(DragManager.MOVE);
}
protected function tree_dragDropHandler(event:DragEvent):void {
}
]]>
</fx:Script>
<fx:Declarations>
<fx:XML id="treeData">
<folder id="root"
label="root"
type="root">
<folder id="folder1"
label="Folder 1"
type="folder">
<folder id="folder2"
label="Folder 2"
type="folder">
<item id="item1"
label="Item 1"
type="item"/>
<item id="item2"
label="Item 2"
type="item"/>
<item id="item3"
label="Item 3"
type="item"/>
<item id="item4"
label="Item 4"
type="item"/>
<item id="item5"
label="Item 5"
type="item"/>
</folder>
</folder>
<folder id="folder3"
label="Folder 3"
type="folder"/>
<folder id="folder4"
label="Folder 4"
type="folder"/>
<folder id="folder5"
label="Folder 5"
type="folder"/>
</folder>
</fx:XML>
</fx:Declarations>
<mx:Tree id="tree"
left="29"
right="28"
top="28"
bottom="27"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="true"
dataProvider="{treeData}"
labelField="@label"
dragEnter="tree_dragEnterHandler(event)"
dragOver="tree_dragOverHandler(event)"
dragDrop="tree_dragDropHandler(event)"
showRoot="false">
</mx:Tree>
</s:WindowedApplication>
令人沮丧的是,默认的拖放功能几乎提供了实现这一点所需的一切,但还不够。看起来IlyaZ的答案应该有效,但这可能是Flex的mx:Tree控件中的一个bug 正如SunilD所提到的,我最终通过滚动自己的拖放实现实现了这一点。下面为将来可能遇到相同问题的任何人提供了代码 请注意,当用户在
maxDropIndex
和maxDropIndex+1
之间的边界上拖动时,仍然存在一个小的视觉反馈问题:在边界的下部,放置指示器将移动,以指示可以在文件夹级别放置项目。我仍然在寻找一个很好的解决方案(有人能告诉我树的来源吗?)
maxDropIndex){
跟踪(“防止跌落”);
DragManager.showFeedback(DragManager.NONE);
this.tree.hideDropFeedback(事件);
返回;
}
跟踪(“允许下降”);
DragManager.showFeedback(DragManager.MOVE);
this.tree.showDropFeedback(事件);
}
受保护的函数树\u dragDropHandler(事件:DragEvent):无效{
跟踪(“dragDropHandler”);
}
受保护的函数树\u mouseMoveHandler(事件:MouseEvent):无效{
//看看我们是否应该开始拖动操作
如果(event.buttonDown&&!拖动&tree.selectedItem&&tree.selectedItem.@type==“item”){
//TODO:根据当前选定的索引计算最小和最大阻力索引
minDropIndex=2;
maxDropIndex=7;
//开始拖动
拖动=真;
var dragSource:dragSource=new dragSource();
addData(tree.selectedItem,“tree\u item\u node”);
doDrag(IUIComponent(event.currentTarget)、dragSource、event);
}
}
受保护的函数树\u dragCompleteHandler(事件:DragEvent):无效{
跟踪(“拖动完成:不再拖动”);
this.tree.hideDropFeedback(事件);
拖动=假;
}
]]>
尝试将所有逻辑放入dragEnterHandler中-文档说明应使用DragEvent.DRAG\u ENTER(而不是DragEvent.DRAG\u OVER)dragEnterHandler()仅在拖动开始时调用一次。我希望能够在拖动过程中根据光标下的项目更改反馈。这是因为当您在树的内置拖放行为后立即将拖动反馈设置为“无”时,会将其设置回“移动”。显示了两个拖放示例,一个用于非列表控件,另一个用于基于列表的控件(如树)。在基于列表的示例中,您有3个选择:使用内置行为、滚动您自己的行为,或者使用两者的组合。您正在执行后一种操作,当您将拖动反馈设置为“无”时,它将被默认行为覆盖。
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="354"
height="480">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.core.DragSource;
import mx.core.IUIComponent;
import mx.core.mx_internal;
import mx.events.DragEvent;
import mx.events.FlexEvent;
import mx.managers.DragManager;
protected var dragging:Boolean = false;
protected var minDropIndex:int = 0;
protected var maxDropIndex:int = 0;
protected function tree_dragEnterHandler(event:DragEvent):void {
// only items can be dropped
if (event.dragSource.hasFormat("tree_item_node")) {
DragManager.acceptDragDrop(IUIComponent(event.currentTarget));
trace("accepting DragDrop");
} else {
event.preventDefault();
DragManager.showFeedback(DragManager.NONE);
trace("rejecting DragDrop");
}
}
protected function tree_dragOverHandler(event:DragEvent):void {
var index:int = tree.calculateDropIndex(event);
if (index < minDropIndex || index > maxDropIndex) {
trace("preventing drop");
DragManager.showFeedback(DragManager.NONE);
this.tree.hideDropFeedback(event);
return;
}
trace("allowing drop");
DragManager.showFeedback(DragManager.MOVE);
this.tree.showDropFeedback(event);
}
protected function tree_dragDropHandler(event:DragEvent):void {
trace("dragDropHandler");
}
protected function tree_mouseMoveHandler(event:MouseEvent):void {
// see if we should start a drag operation
if (event.buttonDown && !dragging && tree.selectedItem && tree.selectedItem.@type == "item") {
// TODO: calculate the min and max drag indices from currently-selected index
minDropIndex = 2;
maxDropIndex = 7;
// start the drag
dragging = true;
var dragSource:DragSource = new DragSource();
dragSource.addData(tree.selectedItem, "tree_item_node");
DragManager.doDrag(IUIComponent(event.currentTarget), dragSource, event);
}
}
protected function tree_dragCompleteHandler(event:DragEvent):void {
trace("dragComplete: no longer dragging");
this.tree.hideDropFeedback(event);
dragging = false;
}
]]>
</fx:Script>
<fx:Declarations>
<fx:XML id="treeData">
<folder id="root"
label="root"
type="root">
<folder id="folder1"
label="Folder 1"
type="folder">
<folder id="folder2"
label="Folder 2"
type="folder">
<item id="item1"
label="Item 1"
type="item"/>
<item id="item2"
label="Item 2"
type="item"/>
<item id="item3"
label="Item 3"
type="item"/>
<item id="item4"
label="Item 4"
type="item"/>
<item id="item5"
label="Item 5"
type="item"/>
</folder>
</folder>
<folder id="folder3"
label="Folder 3"
type="folder"/>
<folder id="folder4"
label="Folder 4"
type="folder"/>
<folder id="folder5"
label="Folder 5"
type="folder"/>
</folder>
</fx:XML>
</fx:Declarations>
<mx:Tree id="tree"
left="29"
right="28"
top="28"
bottom="27"
dragEnabled="false"
dropEnabled="false"
dataProvider="{treeData}"
labelField="@label"
dragEnter="tree_dragEnterHandler(event)"
dragOver="tree_dragOverHandler(event)"
dragDrop="tree_dragDropHandler(event)"
dragComplete="tree_dragCompleteHandler(event)"
mouseMove="tree_mouseMoveHandler(event)"
showRoot="false">
</mx:Tree>
</s:WindowedApplication>