2017-05-04 18 views
0

私はWindows 10 UWPアプリケーションを使用しています。私のXAMLには、プログレスバーを表示するためのStackPanelがあります。したがって、デフォルトでは、StackPanelの可視性は折りたたまれて設定されています。次に、私のコードでは、ユーザーがボタンをクリックした後に可視性を表示するように設定しようとしていますが、何らかの処理を行うメソッドを呼び出します。この例では、パネルは決して表示されません。私がテスト中に気づいWindows 10 UWP StackPanel可視性が動作しない

private void BtnProcess_OnClick(object sender, RoutedEventArgs e) 
    { 
     //Set the progress panel to visible 
     toggleProgressPanel(true); 
     //This is a long running process that can take 3-5 seconds. 
     ProcessRequest(); 
     //Hide the progress panel 
     toggleProgressPanel(false); 
    } 

    private void toggleProgressPanel(bool show) 
    { 
     pnlProgressBar.Visibility = show ? Visibility.Visible : Visibility.Collapsed; 
    } 

ことの一つは、私は明らかのprocessRequestコールとプログレスパネルの隠ぺいをコメントアウトした場合、それはその時点で表示されますということです。私はまた、ProcessRequestメソッド呼び出しの中にパネルを表示して隠してみました。メソッドの最初に表示し、最後に表示していました。

長時間実行されているメソッドのプロセスは実際に実行するのに3〜5秒かかりますので、パネルが表示されないほど速く隠れているわけではありません。

ほとんどの場合、UIの更新の問題のようですが、私はそれを修正する方法がわかりません。呼び出し元のメソッドBtnProcess_OnClickはそのすべてを実行しているため、UIはBtnProcess_OnClickメソッドが完了して返されるまで実際に更新されることはありません。あれは正しいですか?この場合、どうすれば対処できますか?

私はProcessRequestメソッド呼び出しをTask.Runの中に置くことを嫌っています。そのメソッドはUIとかなりの量の対話を行う必要があり、そのソリューションは別のスレッドに置く必要があります。かなりの量のコードを書いてください(私は思っています)。私は行方不明の簡単な解決策がなければならないと思われますか?

ありがとうございます!

+0

ProcessRequest()は非同期メソッドである必要があります。 – Archana

+0

@Archanaお返事ありがとうございます。したがって、非同期の場合は、技術的に別のスレッドにはないので、私はすべてのUIにアクセスできます。私がこれをしなかった理由は、その方法では何も待たないからです。私が理解しているところでは、たとえメソッドを非同期にしても、メソッドの中に待たれることがなければ、同期は実行されます。それは大丈夫ですか、私はまた、無条件にTask.Delay(100)を追加する必要がありますか?それとも待っているようなもの? –

+0

もし3-5秒かかるなら、それで十分でしょう。今あなたのブロッキングUIを3-4秒間表示するので、可視性を変更しても反映されません。 – Archana

答えて

0

Archanaの推奨に従って、私はProcessRequest asyncにメソッド呼び出しを行いました。しかし、私はその方法の中で待っているものはありません。だから、メソッドシグニチャを待たずに非同期としてマークするだけで、同期は(私が理解しているものから)同期して実行されます。だから、非同期に実行するためにそれを強制するために、私は私の方法の中だけでなく、それをマーキング以下を追加した非同期:

await Task.Delay(50); 

は、これはほとんど目立たあるだけの小さな遅延であるだけでなく、私の内部awaitableある何かを与えますメソッドの。

私はこのメソッドの呼び出し側を変更しました。私の場合はボタンプレスイベントを呼び出し、非同期にしてメソッド呼び出しを待っていました。

これは期待通りに機能し、毎回UIが更新されます。

private async void BtnProcess_OnClick(object sender, RoutedEventArgs e) 
{ 
    //Set the progress panel to visible 
    toggleProgressPanel(true); 
    //This is a long running process that can take 3-5 seconds. 
    await ProcessRequest(); 
    //Hide the progress panel 
    toggleProgressPanel(false); 
} 

private void toggleProgressPanel(bool show) 
{ 
    pnlProgressBar.Visibility = show ? Visibility.Visible : Visibility.Collapsed; 
} 

private async Task ProcessRequest() 
{ 
    await Task.Delay(50); 
    //Now do all of my long running code here 
} 

このすべてを行うのprocessRequestの長時間実行されている方法は、作業非同期を維持しながら、私の場合、ボタンのプレスイベントでは、私の長時間実行メソッドの呼び出し元に戻って返すように制御できます。ここでは完全なコードです。コントロールを呼び出し側に戻すことで、UIを更新してUIを更新できるようになります。

希望すると便利です。

+0

長時間実行されたタスクを、そのようなハードコードされた遅延ではなく、 '待ち時間Task.Run(()=> ProcessRequest());に入れてみてください。 –

+0

フィードバックいただきありがとうございます。私のOPの最後の段落を見ると、私はオプションとして言いましたが、呼び出されるProcessRequestメソッドがUIとUIコントロールで行うかなりの作業量を持っているので、私はそれをするのが嫌でした。 Task.Runはメソッドを別のスレッドで実行するよう強制するので、UIにアクセスするたびにディスパッチャでUIスレッドに同期するために、メソッドをかなり変更したり、メソッドに相当量のコードを追加する必要があります。私は何かが欠けていない限り、痛みのように見えます。 –

関連する問題