异步加载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