2010-07-09 70 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%,但我討厭每次我對窗口進行任何更改時都必須檢查這個條件。此外,這種情況可能因機器而異。

我會喜歡它,如果有人能告訴我,我的解決方法是多麼錯誤,告訴我一個更更好的方法來解決我的問題......但直到那麼這將不得不做...