如何防止组件在Flex 3中被拖出舞台

时间:2009-10-16 16:43:01

标签: flex

我认为这个问题有一个简单的解决方案,对我来说不够简单。

问题: 如何限制Flex 3中的TitleWindow被拖出屏幕/舞台?有没有办法将TitleWindow限制在查看区域?

示例:假设我有一个占用100%屏幕的应用程序。接下来,我通过PopUpManager创建一个TitleWindow。然后我可以继续点击并按住(拖动)该窗口离开屏幕,然后释放鼠标按钮。那个窗口现在在某个地方丢失了。有没有办法防止窗口被拖到观察区域之外?

感谢您的帮助。

7 个答案:

答案 0 :(得分:8)

这是一篇非常古老的帖子,但这是另一种方式: 无论是否扩展组件,在TitleWindow定义中添加以下行:move:“doMove(event)” 导入应用程序库(导入mx.core.Application;) 并添加doMove函数:

private function doMove(event:Event):void
{//keeps TW inside layout
    var appW:Number=Application.application.width;
    var appH:Number=Application.application.height;
    if(this.x+this.width>appW)
    {
        this.x=appW-this.width;
    }
    if(this.x<0)
    {
        this.x=0;
    }
    if(this.y+this.height>appH)
    {
        this.y=appH-this.height;
    }
    if(this.y<0)
    {
        this.y=0;
    }
}

答案 1 :(得分:3)

答案 2 :(得分:2)

您可以将其isPopUp属性设置为false,以防止它被置于首位。

var popupWin:TitleWindow = PopUpManager.createPopUp(this, TitleWindow);
PopUpManager.centerPopUp(popupWin);
popupWin.isPopUp = false;

我不知道flex中的DragManager类是否支持边界检查,但如果你真的想允许拖动但是限制其边界,你仍然可以将isPopUp设置为false并实现拖动自己编码,以便组件永远不会超出您指定的限制。检查startDrag()方法以获取示例。界限矩形是关键。

答案 3 :(得分:1)

Flex 4

<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx"
      windowMoving="windowMovingHandler(event)">
.
.
.

protected function windowMovingHandler(event:TitleWindowBoundsEvent):void
{
  var appBounds:Rectangle = parentApplication.getBounds(DisplayObject(parentApplication));
  if(!appBounds.containsRect(event.afterBounds)){
    event.preventDefault();
  }
}

// for better precision, corect appBounds manualy, or, instead of "parentApplication.getBounds..." create new rectangle of your application size

答案 4 :(得分:0)

将TitleWindow子类化,并在标题栏上添加一个画布作为拖动代理。然后你可以明确地用一个边界矩形调用startDrag。

这是非常骷髅,但应该让你走上正轨......

代理的原因是,如果没有画布,可能会在单击titleBar标签时出现一些奇怪的行为。

public class MyTitleWindow extends TitleWindow
{
    public var titleBarOverlay:Canvas;

    override protected function createChildren():void
    {
        super.createChildren();

        if(!titleBarOverlay)
        {
            titleBarOverlay = new Canvas();
            titleBarOverlay.width = this.width;
            titleBarOverlay.height = this.titleBar.height;
            titleBarOverlay.alpha = 0;
            titleBarOverlay.setStyle("backgroundColor", 0x000000);
            rawChildren.addChild(titleBarOverlay);
        }

            addListeners();
    }

    override protected function updateDisplayList(w:Number, h:Number):void
    {
        super.updateDisplayList(w, h);

        titleBarOverlay.width = this.width;
        titleBarOverlay.height = this.titleBar.height;
    }

    private function addListeners():void
    {
        titleBarOverlay.addEventListener(MouseEvent.MOUSE_DOWN, onTitleBarPress, false, 0, true);
        titleBarOverlay.addEventListener(MouseEvent.MOUSE_UP, onTitleBarRelease, false, 0, true);
    }

    private function onTitleBarPress(event:MouseEvent):void
    {
        // Here you can set the boundary using owner, parent, parentApplication, etc.
        this.startDrag(false, new Rectangle(0, 0, parent.width - this.width, parent.height - this.height));
    }

    private function onTitleBarRelease(event:Event):void
    {
        this.stopDrag();
    }
}

答案 5 :(得分:0)

您可以简单地覆盖移动功能并防止“非法”移动(由Panel拖动管理在内部调用)。

我认为你也应该在舞台上调整大小,因为减少它(例如,如果用户调整浏览器窗口的大小)可以将你的弹出窗口发送出舞台,即使没有实际移动它。

public class MyTitleWindow extends TitleWindow {

    public function MyTitleWindow() {
        // use a weak listener, or remember to remove it
        stage.addEventListener(Event.RESIZE, onStageResize, 
                false, EventPriority.DEFAULT, true);
    }

    private function onStageResize(event:Event):void {
        restoreOutOfStage();
    }

    override public function move(x:Number, y:Number):void {
        super.move(x, y);
        restoreOutOfStage();
    }

    private function restoreOutOfStage():void {
        // avoid the popup from being positioned completely out of stage
        // (use the actual width/height of the popup instead of 50 if you
        // want to keep your *entire* popup on stage)
        var topContainer:DisplayObjectContainer =
                Application.application.parentDocument;
        var minX:int = 50 - width;
        var maxX:int = topContainer.width - 50;
        var minY:int = 0;
        var maxY:int = topContainer.height - 50;                
        if (x > maxX) 
            x = maxX
        else if (x < minX)
            x = minX;
        if (y > maxY) 
            y = maxY
        else if (y < minY)
            y = minY;
    }

}

答案 6 :(得分:0)

在TitleWindow的creationComplete处理程序中添加以下内容:

this.moveArea.visible=false;

这将完成这项工作。

另一方面,如果您有自定义皮肤,则可以删除“moveArea”部分。这也应该有用。