我有两个用户控件。第一个包含一个ItemsControl
,我必须用我的第二个用户控件动态填充它。第二个用户控件可能会ÌtemsControl
递归地包含另一个自己,因此初始化它是一个相当繁重的控件。
这是我为SubControl
:
public sealed partial class SubControl : UserControl
{
public SubControl(ModelA item)
{
this.InitializeComponent();
this.DataContext = item;
//if the current item has child items, add them to the ItemsControl:
if(item.SubItems != null)
{
BuildUI(item.SubItems);
}
}
private void BuildUI(List<AbstractModel> data)
{
foreach(var item in data)
{
var dataItem = item as ModelA;
//we only want item of type ModelA in our ItemsControl:
if(dataItem != null)
{
SubElements.Items.Add(new SubControl(dataItem));
}
}
}
}
现在这是我首先为MainControl
who ItemsControl
(称为Elements
) 将包含一组这些的内容SubControl
:
public sealed partial class MainControl : UserControl
{
public MainControl(List<AbstractModel> data)
{
this.InitializeComponent();
BuildUI(data);
}
private void BuildUI(List<AbstractModel> data)
{
foreach(var item in data)
{
var dataItem = item as ModelA;
if(dataItem != null)
{
Elements.Items.Add(item);
}
}
}
}
在构建这个“树”时,我注意到 UI 出现了小幅冻结,但我目前在一台功能非常强大的计算机上工作。我希望该应用程序即使在 Windows Surface RT 等较小的设备上也能顺利运行。所以我改变了MainControl
代码:
public sealed partial class MainControl : UserControl
{
public MainControl(List<AbstractModel> data)
{
this.InitializeComponent();
BuildUI(data);
}
private async void BuildUI(List<AbstractModel> data)
{
var list = new List<SubControl>();
await Task.Run(() =>
{
foreach(var item in data)
{
var dataItem = item as ModelA;
if(dataItem != null)
{
list.Add(new SubControl(dataItem));
}
}
});
foreach(var item in list)
{
Elements.Items.Add(item);
}
}
}
这个想法是在一个不同的线程中构建所有的SubControl
,这样 UI 就不会被阻塞,当所有的用户控件都被初始化后,我们会将它们添加ItemsControl
到MainControl
.
然而,由于数据的编组,这不起作用,即使SubControl
UI 上实际上没有一个数据!它在构建时崩溃,SubControl
这真的很奇怪,因为它对实际的 UI 没有任何影响;它们只是被添加到一个临时的List
.
在后台任务中构建这些用户控件以使 UI 不会冻结可能是什么技巧?