是否可以異步加載tabitems? 在我的情況下,我有一個包含幾個tabitems的選項卡控件。 當用戶點擊一個tabitem時,應用程序會暫時凍結,以加載該tabitem。異步加載TabItem
現在我想改變這一點。當用戶點擊一個tabitem時,會顯示一個動畫,並且在完全加載tabitem之後,將顯示tabitem。
任何想法?
是否可以異步加載tabitems? 在我的情況下,我有一個包含幾個tabitems的選項卡控件。 當用戶點擊一個tabitem時,應用程序會暫時凍結,以加載該tabitem。異步加載TabItem
現在我想改變這一點。當用戶點擊一個tabitem時,會顯示一個動畫,並且在完全加載tabitem之後,將顯示tabitem。
任何想法?
這取決於需要花費很長時間才能加載的內容。
如果數據導致暫停,則會異步加載數據並在數據加載時顯示佔位符。數據加載完成後,您可以將其更改爲實際內容。
這裏有一個例子,
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource TabContentTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource LoadingTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
如果您RelayCommand
改變的SelectedItem
可能是這個樣子:
void ChangeTab(ITabViewModel newTab)
{
// Set loading flag and set tab as Selected
newTab.IsLoading = true;
SelectedTab = newTab;
// Create async task
var asyncTask = new Task(() => newTab.LoadData());
// This runs after task is finished running
asyncTask.ContinueWith(p => newTab.IsLoading = false));
// Start async task
asyncTask.Start();
}
如果這是你的用戶界面,需要花費一些時間來加載,那麼用戶可能只需在第一次加載標籤時處理初始加載時間,但是您可以在切換到已加載標籤extending the TabControl to keep it from destorying it's TabItems時停止延遲。
WPF的TabControl
的默認行爲是當您切換到其他選項卡並在您返回時重新加載它時卸載TabItem
。此解決方法存儲已加載選項卡的ContentPresenter
,並將重新加載保存的選項卡,而不是在切回時加載新的選項卡。
在大多數情況下,UI延遲是由屏幕上的大量UI元素引起的。嘗試並減少標籤上的元素數量。例如,Labels
包含的元素多於TextBlocks
,因此除非您需要特定於標籤的功能,例如選擇,請嘗試使用Labels
而不是TextBlocks
不是'newTab.LoadData()'執行異步到'newTab.IsLoading = false;'? (如果是的話,是不是'ContinueWith Dispatcher.Invoke'是適當的?)(我更新TPL。) – 2012-02-07 17:03:27
@jberger有很多方法異步運行這個,但我把所有的代碼在一個單一的方法保持簡單。 TPL調用應該在異步調用返回之前停止代碼的執行,然後它將完成代碼的其餘部分。如果可能的話,我通常更喜歡將'Dispatcher'保留在我的ViewModel中,因爲它使用UI線程,並且通常使用後臺線程來異步處理數據。 – Rachel 2012-02-07 17:07:29
所以你說'Task.Factory.StartNew'會阻止下一行執行直到任務完成?還是我誤解你的措辭? – 2012-02-07 17:28:08
有一件事我想評論。您應該創建單獨的線程來加載數據。 – 2012-02-07 16:06:15