Form.Show()可以使表单在调用后变为null吗?

时间:2013-04-25 01:46:08

标签: c# winforms forms dotnetbar

这真的是我编程生涯中最烦人的事情:

  1. 我有一个与我的申请一起保存的表格。我没有代码调用某个方法来处理它,我不希望它被任何理由处理,我确定它是否会发生,原因不在我的代码中。此表单是一个自定义表单,其中包含一个名为Next()的方法,此Next()只显示表单上的下一个项目信息。

  2. 当我按下导致调用Next()的按钮时出现了最糟糕的事情,并且有一个异常说“对象引用没有设置为对象的实例”。什么?这是代码,我将表单的引用保存到一个名为“currentShownForm”的Form变量中(我的表单中一次只显示一个,所有这些都应该与我的应用程序一起使用):

    private void ShowForm(CustomRibbonForm form)
    {               
        if (!form.Visible)
        {
            if (currentShownForm != null) currentShownForm.Hide();
            form.Show();                
            currentShownForm = form;                
        }
    }
    
  3. 如果按下Next:

    按钮,则会调用Next()
    currentShownForm.Next();
    

    谜团的形式是.Show(); 使用上面的方法ShowForm(),你认为currentShowForm可以为null ???什么?任何情况?它是null的唯一时刻是在显示第一个表单之前。在显示第一个表格之后,它将是第一个表格,显示的任何其他下一个表格将由它引用。那么它在某些情况下如何变为空? ShowForm()方法中的代码是唯一可以在我的项目中更改currentShownForm引用的代码。

    这真让我很困惑,我无法相信我所看到的。哦,天哪,我对此没有任何线索,任何想法,但我不得不尝试这样最荒谬的事情:

    private void ShowForm(CustomRibbonForm form){
            if (!form.Visible)
            {
                if (currentShownForm != null) currentShownForm.Hide();
                currentShownForm = form; 
                form.Show();                                               
            }
    }
    
    哇,在尝试这个之前,我没有做任何不同的事情,但确实有效。按下“下一步”按钮时,currentShownForm不为null。 ShowForm中两行代码之间交换的魔力是什么?我只想到一个原因,form.Show()以某种方式处理了表单本身?但为什么它仍然显示出来?

    值得注意的是我的表单不是.NET表单(只是继承自.NET表单),它是一个自定义表单,而且它来自DotNetBar lib,哇,我对写一本最讨厌的书有一个想法使用DotNetBar时你应该知道的事情(至少,我已经写了大约5件事,我打赌如果我仍然使用它会有更多的东西)。

    请参阅上面的代码并给我一些解释为什么会这样发生?我无法解释,事实上,我认为这是一个错误。

    非常感谢您的帮助!

    谢谢!

    更新

    现在,至少我知道问题出现的原始事物,但仍然不明白为什么:

    实际上我的表单有一些自定义控件,这里涉及的控件是CustomComboBox。这个comboBox是一个2合1控件,由一个普通的ComboBox(再次,一个DotNetBar组合框,即ComboBoxEx)和一个可聚焦的Label(一个自定义的UserControl)组成。所有控件都注册一个ParentChanged事件,为其父窗体注册一些事件,如下所示:

    protected override void OnParentChanged(EventArgs e){
      if(Parent is CustomRibbonForm){
          ((CustomRibbonForm)Parent).RefreshControls += (s,ev) => {
                  Show();
                  Hide();
          };
      }   
    }
    

    我的表单有一个名为RefreshControls的已定义事件,将在需要时引发。它有一个公共方法来引发名为RefreshAllControls的事件。对该方法的调用放在我的主窗体的Activated事件处理程序中的ShowForm()之后(不是我正在谈论的形式),如下所示:

    Activated += (s,e) => {
        ShowForm(myForm);
        myForm.RefreshAllControls();
    };
    

    以下是下一篇文章:当我注释掉Show();和Hide();在OnParentChanged方法中,它在两种情况下都可以正常工作:

    protected override void OnParentChanged(EventArgs e){
      if(Parent is CustomRibbonForm){
          ((CustomRibbonForm)Parent).RefreshControls += (s,ev) => {
                  //Show();
                  //Hide();
          };
      }   
    }
    

    但如果没有,只有1个案例有效(currentShowForm是在调用form.Show()之前分配的。它更接近问题的原因,但它仍然不容易理解。

    希望您能通过此次更新向我解释一下!谢谢

    下一步更新

    现在我知道currentShownForm为null,因为第一个赋值实际上从未完成,表单显示但currentShownForm = form未执行,因为currentShownForm最初为null,所以在调用ShowForm之后它仍为null( ) 方法。

    它非常接近原因,但它仍然很奇怪:

    private void ShowForm(CustomRibbonForm form){
            if (!form.Visible)
            {
                if (currentShownForm != null) currentShownForm.Hide();
                form.Show(); //<------ I marked a break point here.                                               
                currentShownForm = form; //<----- I also marked a break point here.
            }
    }
    

    在用同一方法标记两个断点后,似乎可以确定所有断点都将逐步完成,但只有第一个断点才能逐步完成。之后,显示主UI并绕过第二个断点????????什么??????????????调用form.Show()之后发生了很多事件,其中大多数都是我的自定义控件中的事件(与Focus,LostFocus和Paint事件有关)。这是我第一次看到这样一个奇怪的代码踩到。现在这非常接近原因,希望你有话要说。谢谢

0 个答案:

没有答案