我高舉兩個用戶控件。 第一個包含一個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));
}
}
}
}
現在,這裏是我寫的第一個用於其ItemsControl
(稱爲Elements
)包含一組這些SubControl
的MainControl
:
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);
}
}
}
}
在構建「樹」時,我注意到了用戶界面的小凍結,但是我目前正在使用功能非常強大的計算機。我希望應用程序即使在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不會凍結一招?
您建議在「另一個線程」上構建UI,而您通過注意到無法在非UI線程上添加控件來自相矛盾。 –
您不能在另一個線程中「構建UI」。 –