2017-05-04 61 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,因爲我在技術上不在另一個線程上,這很好。我沒有這樣做的原因是因爲這種方法沒有什麼是可以等待的。據我所知,即使我使方法異步,如果方法內部沒有任何等待,它仍然會運行同步。是好的還是我還需要添加一個abritrary等待Task.Delay(100);或類似的東西強迫等待? –

+0

如果需要3-5秒,那就足夠了。現在您的屏蔽用戶界面持續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更新。

希望這會有所幫助!

+0

嘗試將你的長時間運行的任務放入一個'await Task.Run(()=> ProcessRequest());'而不是像這樣的硬編碼延遲。 –

+0

感謝您的反饋。如果你看看我的OP的最後一段,我提到這是一個選項,但我不願意這樣做,因爲我調用的ProcessRequest方法在UI和UI控件上有相當多的工作。 Task.Run強制方法在另一個線程上運行,所以我不得不在另一個線程上顯着改變或者在方法中添加相當數量的代碼,以便每次我想要訪問UI時都與調度程序同步回UI線程。看起來像一個痛苦,除非我失去了一些東西。 –