如何确定用户控件何时完全加载并显示? [英] How to determine when the user control is fully loaded and shown?

查看:129
本文介绍了如何确定用户控件何时完全加载并显示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在stackoverflow中已经有一些类似的问题,但是我没有找到答案。



我有一个由几个标签页组成的应用程序。其中一个我一次加载了几十个用户控件的列表。目前我正在加载事件,因为我在这个页面加载之前有一个很小的延迟。我想做的是让UI更加灵敏,并在页面完全加载后填写列表。有没有办法跟踪用户控件何时完全加载内容?



VisibleChanged也不帮助,因为它在任何其他子控件显示之前触发。当我开始加载控制列表时,当一些子控件仍然不可见时,会导致一些丑陋的视觉效果。



编辑 / p>

让它更清楚。我在页面容器上有一些子控件,我有一个我以后要加载的自定义控件的列表。下面几个答案中描述的两种方法的问题是,当我开始加载控件时,他们不会让容器上的其他子控件被显示,这就是为什么我有这些丑陋的效果(我正在这样做BackgroundWorker,但无论如何,它必须与主线程进行交互以将控件添加到列表中)

解决方案

为了使UI你应该发布一个消息( Control.BeginInvoke ),做一个操作,再发一封邮件。然后每次你做任何事情,下一步将在所有用户信息之后排队等待,所以用户操作将被及时处理。



一个非常漂亮的方法是使用 yield return ,让编译器处理所有的关闭逻辑:

  IEnumerable AsyncLoadUI()
{
var p = new Panel();
Controls.Add(p);
yield返回null; (int i = 0; i <50; ++ i){
var txt = new TextBox();


p.Controls.Add(txt);
yield返回null;
}
}

覆盖void OnLoad(EventArgs e)
{
IEnumerator tasks = AsyncLoadUI()GetEnumerator();
MethodInvoker msg = null;
msg = delegate {if(tasks.MoveNext())BeginInvoke(msg); };
msg();
}


There were already a few similar questions on stackoverflow, but I haven't found the answer

I have an application that consists of several tab pages. On one of them I'm loading a list of a few dozen user controls at a time. Currently I'm doing it in Load event and because of that I have a small delay before this page is loaded. What I want to do is to make UI more responsive and fill the list after the page is fully loaded. Is there any way to track when the user control has fully loaded it's content?

VisibleChanged doesn't help too, because it fires before any other child control is shown. That causes some ugly visual effects when some of the child controls are still not visible when I'm starting to load control list.

EDIT

To make it more clear. I have some child controls on a page container and I have a list of custom controls I'm trying to load later. The problem with two approaches described in several answers below is that when I'm starting to load controls they do not let other child controls on the container to be shown and that is why I have those ugly effects (and I'm doing that with BackgroundWorker, but anyway it has to interact with the main thread to add controls to the list)

解决方案

In order to make the UI more responsive, you should post yourself a message (Control.BeginInvoke), do one operation, post yourself another message. Then every time you do anything, the next step will get queued after all user messages, so user actions will get processed promptly.

One really nifty approach is to use yield return and let the compiler take care of all the closures logic:

IEnumerable AsyncLoadUI()
{
    var p = new Panel();
    Controls.Add(p);
    yield return null;

    for( int i = 0; i < 50; ++i ) {
        var txt = new TextBox();
        p.Controls.Add(txt);
        yield return null;
    }
}

override void OnLoad(EventArgs e)
{
    IEnumerator tasks = AsyncLoadUI().GetEnumerator();
    MethodInvoker msg = null;
    msg = delegate { if (tasks.MoveNext()) BeginInvoke(msg); };
    msg();
}

这篇关于如何确定用户控件何时完全加载并显示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆