wpf - 延迟加载 XAML

标签 wpf xaml silverlight

我正在处理的一个项目有一些相当复杂的 XAML,它们明显影响视觉性能。相当多的控件在初始状态下是折叠的;但是,由于他们的 XAML 已解析并构建了可视/逻辑树,因此显示几乎是空白对象的内容非常缓慢。

看起来(并且希望在此处确认)使用初始状态为 Collapsed 的 ContentControl,然后将所需控件作为该 ContentControl 的 DataTemplate 嵌入,将推迟在 DataTemplate 中加载所需控件,直到 ContentControl 可见。

我已经构建了一个通用的 DeferredContentControl 来监听主 UI 控件的 LayoutUpdated 事件(通常是我想要快速显示的任何元素),并且当该 UIElement 的第一个 LayoutUpdated 事件触发时,我使用 Dispatcher 翻转DeferredContentControl 的可见性为 true,这会导致 DeferredContentControl 的 DataTemplate 中的控件实例化。当用户对屏幕的初始 View (现在很快)使用react时,数据模板中的“加载缓慢”(但仍然折叠)控件已准备就绪。

这看起来是一种合理的方法吗?有什么陷阱吗?它似乎在测试 Silverlight 和 WPF 时效果很好,虽然它不会让事情变得更快,但在我的特定场景中它给人的感觉是快了 50%。

最佳答案

我遇到了同样的问题(在 Silverlight 项目中),并以几乎相同的方式解决了它。事实证明它按预期工作,还没有遇到任何陷阱。

当您需要控制解析 xaml 和实例化 View 元素的时间点时,您始终可以使用 DataTemplates (不一定与 ContentControl 并用)。您可以调用DataTemplate.LoadContent()要实例化它,您不必切换 ContentControl 的可见性(尽管在内部这将导致这样的 LoadContent 调用)。

如果需要,请查看我的实现,它甚至可以在构建更重的 VisualTree 时显示静态文本消息:

<DeferredContent HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <DeferredContent.DeferredContentTemplate>
        <DataTemplate>
            <MyHeavyView/>
        </DataTemplate>
    </Controls:DeferredContent.DeferredContentTemplate>
    <TextBlock Text="Loading content..."/>
</Controls:DeferredContent>

和代码
public class DeferredContent : ContentPresenter
{
    public DataTemplate DeferredContentTemplate
    {
        get { return (DataTemplate)GetValue(DeferredContentTemplateProperty); }
        set { SetValue(DeferredContentTemplateProperty, value); }
    }

    public static readonly DependencyProperty DeferredContentTemplateProperty =
        DependencyProperty.Register("DeferredContentTemplate",
        typeof(DataTemplate), typeof(DeferredContent), null);

    public DeferredContent()
    {
        Loaded += HandleLoaded;
    }

    private void HandleLoaded(object sender, RoutedEventArgs e)
    {
        Loaded -= HandleLoaded;
        Deployment.Current.Dispatcher.BeginInvoke(ShowDeferredContent);
    }

    public void ShowDeferredContent()
    {   
        if (DeferredContentTemplate != null)
        {
            Content = DeferredContentTemplate.LoadContent();
            RaiseDeferredContentLoaded();
        }
    }

    private void RaiseDeferredContentLoaded()
    {
        var handlers = DeferredContentLoaded;
        if (handlers != null)
        {
            handlers( this, new RoutedEventArgs() );
        }
    }

    public event EventHandler<RoutedEventArgs> DeferredContentLoaded;
}

关于wpf - 延迟加载 XAML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26537300/

相关文章:

c# - 如何将文本 block 与属性绑定(bind)

sql - 如何在 C#/WPF/MVVM 应用程序中处理 ViewModel 和数据库

c# - 如何在 XAML 中将图像剪辑为椭圆

c# - 在 Silverlight 3 中获取当前用户控件或任何 GUI 的屏幕截图

Silverlight 错误消息 [Arg_VersionString]。不知道从哪里开始

wpf - 是否曾在 WPF 或 Silverlight 中做过布料模拟?

wpf - 在 itemscontrol 中设置环绕面板时添加边框

c# - 将 DataGrid 绑定(bind)到 List<T>,但仅显示 T 属性的选择

xaml - Xamarin.Forms 工具栏项目图标大小

c# - 当另一个类中的先决条件属性发生更改时,为依赖属性提高 PropertyChanged?