gpt4 book ai didi

c# - 如何在另一个线程中初始化沉重的控件?

转载 作者:行者123 更新时间:2023-12-03 13:20:20 26 4
gpt4 key购买 nike

我拥有两个用户控件。
第一个包含一个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编写的内容,其 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中。

但是,由于数据的编码,这是行不通的,即使UI上实际上没有单个 SubControl也是如此!在构建真正奇怪的 SubControl时会崩溃,因为它对实际的UI没有任何影响;它们只是被添加到一个临时的 List中。

在后台任务中构建这些用户控件以使UI不会冻结的技巧可能是什么?

最佳答案

Windows UI是非常单线程的。必须创建每个UI控件,并且只能在单个线程中使用。没有办法解决这个问题。

因此,是时候对解决方案进行一些不同的思考了。创建数十个控件是没有问题的。 UI可以很好地处理。您正在谈论将数百或数千个项目添加到列表控件中,那只是一个不可用的UI。因此,正确的解决方案是重新考虑您的UI设计。也许您可以将结果分为几类。

如果您已经考虑过UI设计并且仍然确定要向用户显示成百上千个项目,那么答案就是使用virtualization。这不仅比简单的foreach循环难编码,而且是有效显示大量数据的唯一方法。

关于c# - 如何在另一个线程中初始化沉重的控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19747450/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com