私は 2 つのユーザー コントロールを持ち上げます。最初のものには 1 つが含まれItemsControl
ており、2 番目のユーザー コントロールで動的に入力する必要があります。ÌtemsControl
2 番目のユーザー コントロールには、再帰的に別のユーザー コントロールが含まれている可能性があるため、初期化するのは非常に重いコントロールです。
これが私がしたことです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
の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 に1 つも存在しない場合でも、データのマーシャリングが原因でこれは機能しません。SubControl
実際の UI に影響を与えないため、ビルド中にクラッシュします。これは非常に奇妙です。それらは一時的に追加されるだけList
です。
UI がフリーズしないように、バックグラウンド タスクでこれらのユーザー コントロールを構築するためのトリックは何でしょうか?