private void button26_Click(object sender, EventArgs e)
  {
      listBox1.Items.Add("万万2邻期和尾");
      listBox1.Items.Add("万万3邻期和尾");
       ..
       ..
       .. //加了很多项         while(...) //轮询,如果listBox1每一项都自绘之后,就执行里面的代码
       {
         textBox1.Text = "熊俊";
       }
  }
private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
     {
        // listBox1自绘
     }
请问,上面的代码, listBox1添加项,会导致自绘,如何轮询,当listBox1每一项都自绘了之后,就执行textBox1.Text = "熊俊";
 

解决方案 »

  1.   

    没必要轮询,直接调用Application.DoEvents()后,自绘就自然完成,之后就可以执行其它方法了。当然,如果你不调用“Application.DoEvents()”,说不定还不肯自绘,先执行其它后续过程。
      

  2.   

    对,执行一次Add就自绘一次,如果看不到效果,那只是因为UI线程还得不到响应,必须执行完你的所有代码,你如果插入一行Application.DoEvents()的话,自绘效果就立刻可以看到了。当然,正因为每次调用Add就会自绘,因此为了提高效率,可以屏蔽它频繁的自绘过程,可以在Add方法之前执行listBox1.BeginUpdate();,所有Add方法之后执行listBox1.EndUpdate();,这样添加速度大大提高。
    例如你的代码:
    listBox1.BeginUpdate();
    listBox1.Items.Add("万万2邻期和尾");
    listBox1.Items.Add("万万3邻期和尾");
    ..
    ..
    .. //加了很多项 
    listBox1.EndUpdate();
    Application.DoEvents();//此时界面立刻显示所有添加的内容。
    textBox1.Text = "熊俊";//自绘之后,就执行里面的代码
                
      

  3.   

    自己做一个listview,继承自系统自带的listview
    添加一个属性或者方法来接受item,并且在这个属性或方法在add的时候,触发一个event,这个event在外面执行自绘这样说
    新建一个mylistview控件,继承自listview。
    增加一个属性items{get;set}
    在set的时候,判断item的数量是增加还是减少,反正就是item变化了,如果变化了数量,那么就触发一个自定义的event,这样就达到了每次新增或者减少item的时候,event会自动触发自绘。
    或者增加一个方法,add,用于新增item。在每次调用这个item的时候,方法中就触发event自绘。
      

  4.   

    我是没有看太明白你的问题,感觉你是想要在每次新增一个item的时候就自绘
      

  5.   

    真要提高效率就 listBox1.Items.AddRange
    listBox1.BeginUpdate() 基本没用, Add 不立即执行,我估计它只是发出了要重绘的消息给 ListBox ,想要立即效果就在所有的添加完了后 Application.DoEvents() ,把积压的重绘消息处理掉。
      

  6.   

    BeginUpdate和EndUpdate方法的用法我是知道的,但不知道Application.DoEvents()起什么作用,EndUpdate方法不就是立刻自绘吗?
    还有会不会有这种可能,Application.DoEvents()自绘还没完成,textBox1.Text = "熊俊";就执行了?
      

  7.   

    Application.DoEvents() 会把程序消息队列里的消息全部取出处理掉,Add 之后有重绘消息,一定会在 textBox1.Text 之前执行。
      

  8.   

    Application.DoEvents() 会把程序消息队列里的消息全部取出处理掉,Add 之后有重绘消息,一定会在 textBox1.Text 之前执行。处理消息队列里面的消息,也是需要时间的啊,那还没有处理完,会不会就执行textBox1.Text = "熊俊";了呢?是不是规定了此处阻塞,一定等到消息队列里面的消息处理完之后,才继续执行后面的代码?
      

  9.   

    这样写法它们在同一个线程里处理的,一定是 listBox1_DrawItem 先执行,操作系统会保证
      

  10.   

    哦,我还想问一下
    “这样写法它们在同一个线程里处理的”..........这句话,是不是MSDN的意思
      

  11.   

    你应该学会自己到MSDN上查看Application.DoEvents的用法和作用。你提问得知了有些什么方法后,细节就应该自己研究,当入门后还不能自己研究,学编程将永远不能自立,永远不能走到别人前面去。PS:既然DoEvents是处理当前在消息队列中的所有 Windows 消息,那么在处理结束之前,将不会执行下面一行的代码。
      

  12.   

    没对,我试过了,Application.DoEvents()后面的代码不是同步的,没有阻塞,先执行了
      

  13.   

    代码
    private void button26_Click(object sender, EventArgs e)
    {
        listBox1.DrawMode = DrawMode.OwnerDrawFixed;
        listBox1.Items.Add("万万2邻期和尾");
        Application.DoEvents();
        textBox1.Text = "熊俊";
    }private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        // listBox1自绘
    }
    你在 textBox1.Text = "熊俊"; 和 listBox1_DrawItem 方法里各设置一个断点,你看看哪个断点先到
      

  14.   

    ListBox 的属性 DrawMode 不设置为 OwnerDrawFixed 或 OwnerDrawVariable 它的事件 DrawItem 不会触发的