2010-07-09 68 views
2

在Flex Air应用程序中,如何在活动窗口后面打开窗口?活动窗口后面的Flex打开窗口

我试过下面,我似乎无法得到它的工作

<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" 
         creationComplete="onCreationComplete(event)"> 

    <fx:Script> 
     <![CDATA[ 
      import mx.events.FlexEvent; 

      import spark.components.Window; 

      private var window1:Window = new Window(); 
      private var window2:Window = new Window(); 
      private var timer:Timer  = new Timer(3000,1); 

      private function onCreationComplete(event:FlexEvent):void 
      { 
       window1   = new Window(); 
       window1.title = "Window 1"; 
       window1.width = 200; 
       window1.height = 200; 
       window1.open(false); 
       window1.orderInBackOf(this); 

       window2   = new Window(); 
       window2.title = "Window 2"; 
       window2.width = 200; 
       window2.height = 200; 

       timer.addEventListener(TimerEvent.TIMER_COMPLETE, openWindow2, false, 0, true); 
       timer.start();   
      } 

      private function openWindow2(event:TimerEvent):void 
      { 
       window2.open(false);  
       window2.orderInBackOf(window1); 
      } 
     ]]> 
    </fx:Script> 
</s:WindowedApplication> 

有了这个代码,我希望窗口1到主应用程序窗口的后面打开,并在3秒,窗口2将开放的背后窗口1。但是,如果执行此操作,window1将在主窗口顶部打开,而window2将在window1顶部打开,主应用程序将保留焦点。这看起来像是Flex中的一个错误。如果是的话,是否有解决这个问题的方法?

回答

0

是否有一个特别的原因,您将useWeakReference参数设置为true?否则,你应该只能打电话:

timer.addEventListener(TimerEvent.TIMER_COMPLETE, openWindow2); 

但是,这行代码中存在一个错误。当定时器完成所有周期时,TIMER_COMPLETE事件被触发。你已经设置你的计时器无限地“启动”。所以它永远不会完成它的周期。

您需要修改的代码行下面,你应该得到你的预计业绩:

timer.addEventListener(TimerEvent.TIMER, openWindow2); 




为了解决第二个问题(为什么WINDOW1不会出现后面的应用)。通过orderInBackOf函数的返回值来判断:

Boolean — true if the window was succesfully sent behind; 
      false if the window is invisible or minimized. 

如果窗口不可见,看起来排序失败。可能是这样的,通过在creationComplete处理程序中的代码,您应用程序窗口有机会显示自己之前调用此函数。尝试在openWindow2函数中移动该代码。 Yeilding:

 private function openWindow2(event:TimerEvent):void 
     { 
      window1.orderInBackOf(this); 
      window2.open(false);  
      window2.orderInBackOf(window1); 
     } 

我希望这有助于在某种程度上,

  • gMale

编辑:按我的最后一点试试这个,

 private function openWindow2(event:TimerEvent):void 
     { 
      window1.depth = 5; //arbitrary number 
      window2.depth = 4; 
      window1.open(false); //assumes window1 isn't opened before 
      window2.open(false);      
     } 
+0

耶将useWeakReference WASN没有必要,但是TIMER_COMPLETE是正确的。如果你看看我的代码,我将计时器设置为仅重复一次。所以在第一次运行后,它会触发TIMER_COMPLETE。 嗯,我想问题是,我打电话orderInBackOf窗口之前可见。将window1.orderInBackOf(this)移动到openWindow2,将window1移动到主应用程序的后面。然而,这不是我想要的行为。我想在主应用程序未打开窗口1后面打开window1,然后将其移到后面。我希望有openInBackOf()函数..或打开(false)应该打开它在活动窗口后面 – lordofthefobs 2010-07-09 18:45:16

+0

@Sang:尝试使用打开(true) - 打开窗口焦点时,看看是否有所作为。你对计时器事情是对的,我不知道为什么我第一次误读它。无论如何,我会尝试使用TIMER事件来查看是否有任何变化。 – gMale 2010-07-09 20:21:39

+0

@Sang:这是来自Adobe的[示例应用](http://www.adobe.com/devnet/air/flex/quickstart/controlling_display_order_windows.html) – gMale 2010-07-09 20:31:49

0

所以它看起来像没有一个好方法来解决这个问题。解决方法是为AIREvent.WINDOW_COMPLETE添加事件侦听器,并在事件处理程序中移动窗口。这看起来像“正确的”解决方法,它适用于像我的原始示例这样的简单案例。问题是这种方法在我的代码上无效。

如果您查看sdk中的spark.components.Window代码,您将看到在打开窗口(在commitProperties()中)时会添加Event.ENTER_FRAME的事件侦听器。然后在事件处理函数enterFrameHandler()中保存一个计数器,并在第二帧中调度AIREvent.WINDOW_COMPLETE事件。这让我觉得,AIREvent.WINDOW_COMPLETE事件将触发对第二帧不管窗口的状态,即使livedoc说:

当Window 完成其初始布局并打开基础NativeWindow调度。

我猜我的窗口不是由第二帧创建的,因此orderInBackOf失败。


因此,这里是我的解决方法:

首先,在我的窗口,我重写开放(openWindowActive)。如果openWindowActive为false,则为Event.ENTER_FRAME添加一个事件侦听器。在事件处理程序中,我保留一个计数器,当帧数达到一定数量(现在10)时,我将当前窗口移动到活动窗口的后面。这是一个非常冒险的方式来解决这个问题。我一直在增加限制,现在约有90%的时间成功。我可以继续增加限制,直到我接近100%,但我讨厌每次我对窗口进行任何更改时都必须检查这个条件。此外,这种情况可能因机器而异。

我会喜欢它,如果有人能告诉我,我的解决方法是多么错误,告诉我一个更更好的方法来解决我的问题......但直到那么这将不得不做...