2011-01-21 68 views
1

簡而言之:在Windows窗體中實現阻塞模式視圖/對話框 - 有可能嗎?

我想顯示一個視圖或操作表,並且只有在用戶解除視圖/表單後才繼續執行代碼。所以:第一行顯示視圖,第二行顯示一些結果變量。

具體爲什麼我需要這樣的:

我移植Windows窗體應用程序轉移到iPad上。原始實現具有使用Web服務與服務器通信的通信類。它提供了一些獲取數據的方法。如果用戶仍然有有效的連接,或者出於安全原因必須重新輸入密碼,則可以方便地在每次通話之前進行檢查。 如果需要密碼,.NET類將顯示一個模塊對話框,用於阻止任何進一步的代碼執行,並且如果輸入密碼,則在顯示對話框之前重試最後一次調用。

現在使用CocoaTouch我正面臨一個問題。我用UIActionSheet替換了顯示對話框的代碼。很好的工作,但代碼執行會立即繼續,而在Windows窗體中它會被阻塞(顯示對話框後Windows窗體中的下一行是從對話框中讀取輸入的密碼),直到關閉對話框。

我試過一個Thread.Sleep(),直到用戶關閉UIActionSheet,但Thread.Sleep()也阻止了主循環,我的視圖甚至不會被繪製。

我目前看到的替代方法是更改​​已經工作的類中的所有方法,並給它們返回值:如果需要密碼,則處理它,然後重試。

但是,這意味着我的代碼將不得不添加這些檢查,因爲在任何時候都可能需要密碼。這就是爲什麼它嵌套在Windows Forms的通信類中。

還有其他想法嗎?

René

回答

1

是的,這是可能的。

要做到這一點,你可以做的是手動運行主循環。我沒有設法直接停止主循環,所以我運行0.5秒的主循環並等待用戶響應。

下面的函數展示瞭如何實現上述方法模態查詢:

int WaitForClick() 
{ 
    int clicked = -1; 
    var x = new UIAlertView ("Title", "Message", null, "Cancel", "OK", "Perhaps"); 
    x.Show(); 
    bool done = false; 
    x.Clicked += (sender, buttonArgs) => { 
     Console.WriteLine ("User clicked on {0}", buttonArgs.ButtonIndex); 
clicked = buttonArgs.ButtonIndex; 
    };  
    while (clicked == -1){ 
     NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5)); 
     Console.WriteLine ("Waiting for another 0.5 seconds"); 
    } 

    Console.WriteLine ("The user clicked {0}", clicked); 
    return clicked; 
} 
+0

真棒!謝謝米格爾! – Krumelur 2011-01-28 13:27:39

1

我覺得這個方法使用異步/等待是更好的,和旋轉時不會凍結應用程序遭受該設備,或者當自動滾動干擾並且讓你永遠卡在RunUntil循環中而無法點擊按鈕(至少這些問題很容易在iOS7上重現)。

Modal UIAlertView

Task<int> ShowModalAletViewAsync (string title, string message, params string[] buttons) 
{ 
    var alertView = new UIAlertView (title, message, null, null, buttons); 
    alertView.Show(); 
    var tsc = new TaskCompletionSource<int>(); 

    alertView.Clicked += (sender, buttonArgs) => { 
     Console.WriteLine ("User clicked on {0}", buttonArgs.ButtonIndex);  
     tsc.TrySetResult(buttonArgs.ButtonIndex); 
    };  
    return tsc.Task; 
}  
相關問題