2011-01-21 1 views
1

短い:Windowsフォームのようなブロックモーダルビュー/ダイアログを実装することは可能ですか?

私はビューまたはアクションシートを表示し、ユーザーがビュー/シートを閉じた後にのみコードの実行を続けます。したがって、1行目はビューを表示し、2行目は結果変数を読み込みます。私はこれを必要とする理由を詳細に

私は、Windowsを移植していますがiPadにアプリケーションをオーバーフォーム。元の実装には、Webサービスを使用してサーバーと通信する通信クラスがあります。それは、データを取得するためのいくつかの方法を提供します。都合の良いことに、ユーザが有効な接続をまだ持っている場合、またはセキュリティ上の理由からユーザがパスワードを再入力する必要がある場合は、各コールの前にチェックします。 パスワードが必要な場合、.NETクラスにはモーダルダイアログが表示され、それ以上のコード実行をブロックします。パスワードが入力された場合は、ダイアログを表示する前に最後に呼び出したものを再試行します。

今、私は問題に直面しているココアタッチを使用しています。ダイアログを示すコードをUIActionSheetに置き換えました。 Windowsフォームでは、ダイアログが閉じられるまでブロックされます(ダイアログを表示した後の次の行はダイアログから入力されたパスワードを読み取ることです)。

ユーザーがUIActionSheetを終了するまでThread.Sleep()を試しましたが、Thread.Sleep()もメインループをブロックし、私のビューは描画されません。

私が現在見ている代替案は、すでに動作しているクラスのすべてのメソッドを変更し、戻り値を与えることです。パスワードが必要な場合は、それを処理してから、再試行してください。

しかし、これは私のコード全体で、いつでもパスワードが必要な場合があるため、これらのチェックを追加する必要があることを意味します。そのため、Windowsフォームの通信クラスにネストされています。

他のアイデアはありますか?

ルネ

答えて

1

はい、可能です。

これを行うには、メインループを手動で実行する必要があります。私はmainloopを直接停止させていないので、代わりに0.5秒間mainloopを実行し、ユーザーが応答するまで待ってください。

次の関数を使用すると、上記のアプローチとモーダルクエリを実装する方法を示しています。

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

+0

ブロックループを実行するときに問題があります。私はEntryEndedイベントでこのコードを持っており、ユーザーがデバイスを回転させるとループは終了せず、アプリケーションがハングアップしているように見えます。 – danmiser

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; 
}  
関連する問題