我正在处理的一个项目有一些相当复杂的 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/