1

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

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

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

    private void ShowForm(CustomRibbonForm form)
    {               
        if (!form.Visible)
        {
            if (currentShownForm != null) currentShownForm.Hide();
            form.Show();                
            currentShownForm = form;                
        }
    }
    

如果我按下 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();                                               
        }
}

哇,在尝试这个之前,我不认为它可以让任何事情变得不同,但它确实有效。当我按下 Next 按钮时,currentShownForm 不为空。ShowForm中两行代码的交换有什么魔力???我认为只有一个原因,form.Show() 以某种方式处理了表单本身?但为什么它仍然显示?

值得注意的是我的表单不是 .NET 表单(只是继承自 .NET 表单),它是一个自定义表单,而且它再次来自 DotNetBar lib,哇,我有一个想法,关于写一本你应该写的最烦人的事情知道使用 DotNetBar 时(至少,我有大约 5 件事要写,我敢打赌,如果我仍然使用它,还会有更多)。

请查看上面的代码,并解释一下为什么会发生这种情况?我无法解释它,事实上,我想这是一个错误。

您的帮助将不胜感激!

谢谢!

更新

现在,至少我知道问题发生的原始原因,但仍然不明白为什么:

实际上我的表单有一些自定义控件,这里涉及到的控件是一个CustomComboBox。这个组合框是一个二合一控件,由一个普通的组合框(同样,一个 DotNetBar 组合框,即 ComboBoxEx)和一个可聚焦的标签(一个自定义的用户控件)组成。所有控件都注册一个 ParentChanged 事件来为其父窗体注册一些事件,如下所示:

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

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

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

接下来是:当我注释掉 Show(); 和隐藏();在 OnParentChanged 方法中,它在两种情况下都可以正常工作:

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

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

希望您能通过这次更新向我解释一些事情!谢谢

下一个更新

现在我知道 currentShownForm 为空,因为第一个分配实际上从未完成,显示了表单currentShownForm = form但未执行,并且因为 currentShownForm 最初为空,在调用 ShowForm() 方法后它仍然为空。

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

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.
        }
}

用同样的方法标出两个连续的断点后,似乎可以确定所有的断点都会被单步通过,但只有第一个断点被单步通过。之后显示主界面,绕过第二个断点?????????什么??????????????在调用 form.Show() 之后发生了许多事件,其中大多数是我的自定义控件中的事件(与 Focus、LostFocus 和 Paint 事件有关)。这是我第一次看到如此奇怪的代码步进。现在这很接近事业,希望你有话要说。谢谢

4

0 回答 0