我创建了很多具有大量背景图像的UserControl。我把它们放在一张表格上。表单加载完成后,一切正常。 问题是 - 表格出现在屏幕上需要10秒钟。
我在互联网上搜索并找到了一个解决方案 - 显示一个临时表格,上面写着“请等待......”。
现在我想知道是否有可能用ProgressBar
替换“请稍候”消息。不是一个人。实际上会显示表单加载进度的那个。
我检查了代码,结果发现重要部分位于InitializeComponent
。 InitializeComponent
是自动生成的,因此我不应手动编辑,对吧?
我试图将InitializeComponent
移到单独的线程。事实证明这是一个坏主意,因为不应该在不同的线程中创建控件。
答案 0 :(得分:0)
答案 1 :(得分:0)
如您所见,您无法在另一个线程中运行InitializeComponent
方法。但是你可以延迟一些初始化。如果您确定图像加载速度太慢(是否从远程位置下载?),则从设计器中删除图像初始化(例如,通过使Image
属性无效)并仅在表单后加载它们显示:
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
progressBar1.Visible = true;
progressBar1.Value = 0;
await LoadImages();
progressBar1.Visible = false;
}
// Just represents a simple source-target mapping so you can associate the loaded images with their targets
// Here I use a path-control mapping just for the case of the example
private ICollection<KeyValuePair<string, Control>> GetImageMapping()
{
var basePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonPictures), "Sample Pictures");
var mapping = new Dictionary<string, Control>
{
[Path.Combine(basePath, "Tulips.jpg")] = this, // form1
[Path.Combine(basePath, "Chrysanthemum.jpg")] = button1,
// etc, eg. myUserControl1...
};
return mapping;
}
private async Task LoadImages()
{
var mapping = GetImageMapping();
progressBar1.Maximum = mapping.Count;
foreach (var item in mapping)
{
var image = await LoadImage(item.Key);
item.Value.BackgroundImage = image;
progressBar1.Value++;
}
}
private async Task<Image> LoadImage(string imagePath)
{
// This makes 1s delay for each image to imitate slow loading. You do NOT need this line actually.
await Task.Delay(1000);
// Only this part will be executed in another thread:
return await Task.Run<Image>(() =>
{
// or download it, load from a stream, resource, whatever...
var result = Image.FromFile(imagePath);
return result;
});
}
请注意,表单可以在加载进度完成之前关闭,因此您可能还需要一些额外的检查。