【发布时间】:2019-02-06 07:46:26
【问题描述】:
我有一个选项卡控件,其中选项卡是在运行时创建的。选项卡的内容将是几个用户控件之一,每个控件都包含数百个其他控件。由于创建这些用户控件需要很长时间,因此我试图找到一种方法来重用它们,而不是为每个选项卡创建一个新实例。
我正在使用 DataTemplate 设置标签页内容,如下所示:
<DataTemplate>
<ScrollViewer Content="{Binding Content}" />
</DataTemplate>
Content 是我想在选项卡中显示的视图的视图模型。
在其他地方,我使用数据模板将每个视图模型映射到一个视图,例如
<DataTemplate DataType="{x:Type vm:MyViewModel1}">
<ctl:CacheContentControl ContentType="{x:Type ctl:MyView1}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MyViewModel2}">
<ctl:CacheContentControl ContentType="{x:Type ctl:MyView2}" />
</DataTemplate>
CacheContentControl 是我用于缓存的 ContentControl 的包装器:
public class CacheContentControl : ContentControl
{
private static Dictionary<Type, Control> cache = new Dictionary<Type, Control>();
public CacheContentControl()
{
Unloaded += CacheContentControl_Unloaded;
}
private void CacheContentControl_Unloaded(object sender, RoutedEventArgs e)
{
Content = null;
}
private Type _contentType;
public Type ContentType
{
get { return _contentType; }
set
{
_contentType = value;
Content = GetView(_contentType);
}
}
public Control GetView(Type type)
{
if (!cache.ContainsKey(type))
{
cache.Add(type, (Control)Activator.CreateInstance(type));
}
return cache[type];
}
}
这确保 DataTemplate 在创建新实例之前首先检查缓存以查看它是否可以重用控件。
这适用于创建的任何新标签。第一个选项卡与预期的一样慢,因为它需要创建初始控件,但使用相同控件的所有后续选项卡几乎立即加载。我遇到的问题是,当我单击返回上一个选项卡时,控件不再出现并且选项卡为空白。
我猜这是因为我不能在同一个表单上多次显示同一个控件实例,这是有道理的。我已经能够通过为我的 CacheContentControl 处理 IsVisibleChanged 事件来解决它,如下所示:
private void CacheContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (IsVisible && ContentType != null)
{
Control ctl = GetView(_contentType);
ctl.DataContext = DataContext;
Content = ctl;
}
else
{
Content = null;
}
}
When a tab loses focus it removes the control, the tab that receives focus can then retrieve the control from the cache which seems to work.
问题是速度又变慢了,我不知道为什么。显然,可以毫不拖延地将控件实例从一个选项卡移动到另一个选项卡,因为每次我创建一个新选项卡时都会这样做。 DataTemplate 必须做一些不同的事情来更改控件的父级?
【问题讨论】:
标签: c# wpf mvvm datatemplate