【问题标题】:Load a TabItem asynchronously异步加载 TabItem
【发布时间】:2012-02-07 16:01:49
【问题描述】:

是否可以异步加载tabitems? 就我而言,我有一个包含一些 tabitems 的选项卡控件。 当用户点击一个 tabitem 时,应用程序会冻结一小段时间,以加载 tabitem。

现在我想改变它。当用户点击一个 tabitem 时,会显示一个动画,并且当 tabitem 完全加载后,会显示这个 tabitem。

谁有想法?

【问题讨论】:

  • 我想评论一件事。您应该创建单独的线程来加载数据。

标签: c# wpf asynchronous


【解决方案1】:

这取决于加载时间长。

如果数据导致暂停,则异步加载数据并在数据加载时显示占位符。数据加载完成后,您可以将其更改为您的实际内容。

这是一个例子,

<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();
}

如果是您的 UI 需要一段时间来加载,那么用户可能只需要在第一次加载选项卡时处理初始加载时间,但是您可以通过 @987654321 在切换到已加载的选项卡时停止延迟@。

WPF 的TabControl 的默认行为是在您切换到不同的选项卡时卸载TabItem,并在您返回时重新加载它。此解决方法存储已加载选项卡的ContentPresenter,并在切换回时重新加载保存的选项卡而不是加载新选项卡。

在大多数情况下,UI 延迟是由屏幕上的大量 UI 元素引起的。尝试减少选项卡上的元素数量。例如,Labels 包含的元素多于 TextBlocks,因此除非您需要特定于标签的功能(如选择),否则请尝试使用 Labels 而不是 TextBlocks

【讨论】:

  • 不是newTab.LoadData() 异步执行到newTab.IsLoading = false; 吗? (如果是,ContinueWith Dispatcher.Invoke 不合适吗?)(我是 TPL 的新手。)
  • @jberger 有很多方法可以异步运行,但是我将所有代码放在一个方法中以保持简单。该 TPL 调用应该停止代码的执行,直到异步调用返回之后,然后它将完成其余代码。如果可能的话,我通常更喜欢将 Dispatcher 保留在我的 ViewModel 之外,因为它使用 UI 线程,并且通常使用后台线程来异步处理数据。
  • 所以你是说Task.Factory.StartNew 会阻止下一行执行,直到任务完成?还是我误解了你的措辞?
  • @jberger 哦,对不起,你是对的。我查看了一些旧代码,发现我正在使用await/async 来保存代码。我会更新我的示例,谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
相关资源
最近更新 更多