if (this.Controls.Count > 0) {  //描绘之前将现有已经创建的button释放
                CtlNum = this.Controls.Count;
                for (i = 0; i < CtlNum; i++) {
                  this.Controls[i].Dispose();                }
                this.Controls.Clear();
            }
           
            for (i = StartNum; i < DisplayNum; i++) {
      
                abton = new button();
                abton.Name = "abton" + i.ToString();;
                            
                 this.Controls.Add(abton);
                    
                }
                
            }
这些代码是放在自绘控件的onpaint里,编译顺利通过,只是在将该控件放到form里,发生运行时错误,报错为"Cannot access a disposed object.
Object name: 'Button'".郁闷死我,不知道什么原因,按理由,不该报错的.找了1天,找不出原因

解决方案 »

  1.   

    要先收集子控件到数组,然后clear,然后用数组调用disposed。clear内部会访问子控件的属性,所以出异常。
      

  2.   

    photoplan() ( ) 信誉:100  2007-09-16 09:36:28  得分: 0  
     
     
       要先收集子控件到数组,然后clear,然后用数组调用disposed。clear内部会访问子控件的属性,所以出异常。
      
     
    _______________________________________
    能否给个简单的例子,谢谢
      

  3.   

    Control[] controls = new Control[panel1.Controls.Count];
    panel1.Controls.CopyTo(controls, 0);foreach (Control c in controls)
    {
        c.Dispose();
    }
    不用 clear,dispose 时自动从父控件中移除
      

  4.   

    还是 clear 吧,这样Control[] controls = new Control[panel1.Controls.Count];
    panel1.Controls.CopyTo(controls, 0);
    panel1.Controls.clear();foreach (Control c in controls)
    {
        c.Dispose();
    }
    我也有点糊涂,你多试试
      

  5.   

    在普通的函数里,这些代码都没问题
    但是在onpaint里就会出问题,似乎是再次绘制时,controls.add了dispose的控件,但逻辑上找不到任何错误,郁闷
      

  6.   

    hdt(倦怠) ( ) 信誉:120  2007-9-16 20:17:39  得分: 0  
     
     
       
    不能访问已被回收的对象
    _____________________________________
    兄弟,这个英文我还是看得懂的,主要是找不到错的地方,我控制绘制次数,一点问题都没,就是只让它绘制1次,那就没有问题
      
     
      

  7.   

    把this.Controls[i].Dispose();改为this.Controls.RemoveAt(i);Add()和RemoveAt()是一对操作的。不要用Dispose();
      

  8.   

    1、你的代码逻辑有问题
    onpaint 事件:只要界面有变化,就会触发,所以,最好添加删除控件不要在这里进行,添加删除会自动调用onpaint 。
    2、删除控件的顺序错误,ls 大致正确,详细如下
      a、从事件中移除事件处理程序。在 Visual Basic 中,请使用 RemoveHandler 关键字;在 C# 中,请使用 -= 运算符。 
      b、使用 Remove 方法,从该面板的 Controls 集合中删除所需的控件。 
      c、调用 Dispose 方法,释放该控件使用的所有资源。
      

  9.   

    试试:
    if (this.Controls.Count > 0) {  //描绘之前将现有已经创建的button释放
                    CtlNum = this.Controls.Count;
                    this.Controls.Clear();
                }
               
                for (i = StartNum; i < DisplayNum; i++) {
          
                    button abton = new button();
                    abton.Name = "abton" + i.ToString();;
                                
                     this.Controls.Add(abton);
                        
                    }
                    
                }
      

  10.   

    for (i = 0; i < CtlNum; i++) {
                      this.Controls[i].Dispose();                }
    这部分代码是没有必要
    this.Controls.Clear();包括这部分功能