Apache flex 如何防止组件被拖出Flex3中的阶段

Apache flex 如何防止组件被拖出Flex3中的阶段,apache-flex,Apache Flex,我认为这个问题有一个简单的解决方案,只是对我来说还不够简单 问题: 如何约束Flex3中的标题窗口不被拖离屏幕/舞台?有没有办法将标题窗口限制在查看区域 示例:假设我有一个占据100%屏幕的应用程序。接下来,我通过PopUpManager创建一个TitleWindow。然后,我可以继续点击并按住(拖动)屏幕上的窗口,然后释放鼠标按钮。那个窗口现在在屏幕的某个地方消失了。有没有办法防止窗口被拖出查看区域 提前感谢您的帮助。您可以将其ispoup属性设置为false,以防止其被拖动 var popu

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

问题: 如何约束Flex3中的标题窗口不被拖离屏幕/舞台?有没有办法将标题窗口限制在查看区域

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


提前感谢您的帮助。

您可以将其
ispoup
属性设置为
false
,以防止其被拖动

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

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

对标题窗口进行子类化,并在标题栏上添加画布作为拖动代理。然后,您可以使用边界矩形明确地调用startDrag

这是很简单的,但应该让你走上正轨

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

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();
    }
}

这是一篇非常古老的帖子,但这里有另一种方式: 无论是否扩展组件,在标题窗口定义中添加以下行: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;
    }
}
私有函数doMove(事件:事件):无效
{//将TW保留在内部布局中
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.xappH)
{
this.y=appH-this.height;
}

if(this.y您可以简单地覆盖move函数并防止“非法”移动(由面板拖动管理在内部调用)

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

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;
    }

}
公共类MyTitleWindow扩展了TitleWindow{
公共函数MyTitleWindow(){
//使用弱侦听器,或记住将其删除
stage.addEventListener(Event.RESIZE、onStageResize、,
false,EventPriority.DEFAULT,true);
}
stageresize上的私有函数(事件:事件):void{
恢复阶段();
}
覆盖公共功能移动(x:编号,y:编号):无效{
超级移动(x,y);
恢复阶段();
}
私有函数restoreoutostage():void{
//避免弹出窗口完全脱离舞台
//(如果需要,请使用弹出窗口的实际宽度/高度,而不是50)
//想让您的*整个*弹出窗口保持在舞台上)
var topContainer:DisplayObjectContainer=
Application.Application.parentDocument;
var minX:int=50-宽度;
var maxX:int=topContainer.width-50;
var minY:int=0;
var maxY:int=topContainer.height-50;
如果(x>maxX)
x=maxX
else if(xmaxY)
y=最大值
否则,如果(y
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

.
.
.
受保护的函数windowMovingHandler(事件:TitleWindowBoundsEvent):无效
{
var-appBounds:Rectangle=parentApplication.getBounds(DisplayObject(parentApplication));
如果(!appBounds.containsRect(event.afterBounds)){
event.preventDefault();
}
}
//为了获得更好的精度,可以手动corect appBounds,或者,代替“parentApplication.getBounds…”创建应用程序大小的新矩形

对于flex 4,答案如下:

在标题Windows的creationComplete处理程序中添加以下内容:

this.moveArea.visible=false;
这就行了


另一方面,如果您有自定义蒙皮,则可以删除“moveArea”部分。这也应该可以。谢谢你的回复。是的,我可以将isPop属性设置为false。但是,如果可能的话,我仍然希望窗口可以拖动。建议不错。谢谢。如果没有解决方案,我可能不得不走这条路。他们的示例将mouseUp事件添加到拖动的对象中-你可能想将其更改为
阶段
,以便即使用户在标题窗口外释放鼠标,它也会被触发。重写TitleWindow类以访问其受保护的
标题栏
属性。将mouseDown事件添加到标题栏,在mouseDownHandler中,调用TitleWindow.startDrag并将mouseUp侦听器添加到舞台。从MouseHandler调用stopDrag。我希望忽略了某个对象上的某个属性。但是您提供的解决方案很有希望。经过一些工作后,我使用了您的原始解决方案;ispoup=false。感谢您的帮助。需要覆盖什么?为什么不直接将事件侦听器添加到标题栏?感谢您的反馈Daniel我感谢您的努力和时间请回答。赫克托!你做到了!你就是那个人!这正是我要找的。谢谢。