这真的是我编程生涯中最烦人的事情:
我有一个与我的申请一起保存的表格。我没有代码调用某个方法来处理它,我不希望它被任何理由处理,我确定它是否会发生,原因不在我的代码中。此表单是一个自定义表单,其中包含一个名为Next()的方法,此Next()只显示表单上的下一个项目信息。
当我按下导致调用Next()的按钮时出现了最糟糕的事情,并且有一个异常说“对象引用没有设置为对象的实例”。什么?这是代码,我将表单的引用保存到一个名为“currentShownForm”的Form变量中(我的表单中一次只显示一个,所有这些都应该与我的应用程序一起使用):
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();
}
}
哇,在尝试这个之前,我没有做任何不同的事情,但确实有效。按下“下一步”按钮时,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事件有关)。这是我第一次看到这样一个奇怪的代码踩到。现在这非常接近原因,希望你有话要说。谢谢