【问题标题】:Why can I not call a form object in two events?为什么我不能在两个事件中调用表单对象?
【发布时间】:2019-07-26 04:08:00
【问题描述】:

我正在制作一个带有两个按钮的添加联系人表单,添加联系人和编辑联系人。当用户点击添加联系人时,会弹出另一个表单,用户可以在其中添加联系人信息。

我想为他们提供编辑该信息的选项,方法是点击应该弹出相同表单的“编辑联系人”按钮。

但是它不允许我两次调用表单的对象,说我不能在添加按钮之后按下编辑按钮。

如何调用表单对象两次?

    //instatiating an object of the form
    FormContact contactForm = new FormContact();

    public FormManager()
    {
        InitializeComponent();
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
        //displaying it when the user clicks add button
        contactForm.Show();
    }

    private void btnEdit_Click(object sender, EventArgs e)
    {
        //trying to display it again but gives this exception

        ///System.ObjectDisposedException: 'Cannot access a disposed 
        ///object.
        ///Object name: 'FormContact'.'

        contactForm.Show();
    }

        Error:
        ///System.ObjectDisposedException: 'Cannot access a disposed 
        ///object.
        ///Object name: 'FormContact'.'

【问题讨论】:

    标签: c# forms winforms


    【解决方案1】:

    问题是您在显示表单后将其关闭。

    1. 您单击“显示”按钮
    2. 显示了您唯一的表单实例
    3. 用右上角的 X 将其关闭
    4. 运行时在表单关闭后销毁(处置)表单
    5. 您尝试再次显示它,但这个它已经消失了,已被丢弃,不再存在,等待被垃圾回收

    每次打开时都创建一个新表单(为了减少代码混乱,将相同的事件处理程序分配给两个按钮单击,或者如果您希望它们最终编码不同,则将其复制粘贴两次):

    private void btnAddOrEdit_Click(object sender, EventArgs e)
    {
        new FormContact().Show();
    }
    

    或者拦截 FormContact 表单的 FormClosing 事件并取消关闭,并改为执行Hide(),这样您的表单就不会被破坏,而是变得不可见。然后它仍然存在并且下次可以是Show()n。要处理该事件,请打开 FormContact 设计器,单击表单背景中的任意位置,单击属性网格中的闪电,双击 FormClosing 条目:

    private void FormClosing(object sender, FormClosingEventArgs e){
      e.Cancel = true;
      this.Hide();
    }
    

    您选择哪种方法取决于您希望程序的行为方式:

    如果您每次都创建一个新表单,并且您 Show 而不是 ShowDialog 您的用户可以单击两次添加并查看两个表单。然后可以单击添加 10 次并查看 10 个表单。使用 ShowDialog 意味着在 FormContact 关闭之前,主窗口将不再接受任何点击。你可能想要也可能不想要这个

    如果您Hide(不关闭;隐藏与关闭不同)和Show 相同的表单而不是创建一个新表单,那么用户可以点击添加 10 次,但他们仍然只能看到一个表单

    【讨论】:

      【解决方案2】:

      FormContact contactForm = new FormContact(); 是一个成员变量,它的作用域是私有的,对整个类都是可见的。

      在你第一次显示表单之后:

      contactForm.Show();

      表单已经显示。因此,如果您再次调用Show,它不会做任何事情,因为表单/类的实例已经显示出来了。

      如果要显示表单的两个实例,则需要实例化两个实例,例如:

      private void btnAdd_Click(object sender, EventArgs e)
      {
          FormContact contactForm = new FormContact();
          contactForm.Show();
      }
      
      private void btnEdit_Click(object sender, EventArgs e)
      {
          FormContact contactForm = new FormContact();
          contactForm.Show();
      }
      

      或者创建两个实例:

      FormContact contactForm1 = new FormContact();
      FormContact contactForm2 = new FormContact();
      
      private void btnAdd_Click(object sender, EventArgs e)
      {
          contactForm1.Show();
      }
      
      private void btnEdit_Click(object sender, EventArgs e)
      {
          contactForm2.Show();
      }
      

      或者在Constructor的参数中添加一个参数来表示Add或者Edit,例如:

      public class FormContact
      {
         public FormContact(int id) 
         {
           if (id > 0)
           {
              //Load contact for Editing
           }
           else
           {
              //Clear all fields for Adding
              foreach(var ctrl in this.Controls)
              {
                   if (ctrl Is TextBoxBase) ctrl.Text = string.Empty
                   //TODO other controls types... if (ctrl Is ....
              }
           }
         }
      }
      

      然后你可以调用它传递一个contactID来编辑或0来添加:

      FormContact contactForm = new FormContact(contactID);
      contactForm.Show();
      

      【讨论】:

      • 嗯,谢谢你,我会试试的,我没有这样做的原因是因为我认为它会创建一个新的contactForm,而不是调用同一个。就像因为它正在编辑一样,我希望从 add_click 事件添加的 SAME 信息再次显示在 edit_Click 事件中
      【解决方案3】:

      我还有另一个答案,在这两种方法中都只是以模态方式显示您的表单:

      contactForm.ShowModal();

      【讨论】:

        猜你喜欢
        • 2013-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-02
        相关资源
        最近更新 更多