包含UserControl的WinForms表单在我尝试以设计模式显示时会引发异常,但在运行或调试程序时会正常运行。
设计师说:
变量'fpInfoA'未声明或从未分配。
ResearchTool fMain.Designer.cs行:282列:1 呼叫堆栈
在System.ComponentModel.Design.Serialization.CodeDomSerializerBase.Error(IDesignerSerializationManager manager,String exceptionText,String helpLink) 在System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager,String name,CodeExpression expression) 在System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeExpression(IDesignerSerializationManager manager,String name,CodeExpression expression) 在System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager,CodeStatement statement)
但是,看起来变量是按照我在InitializeComponent
private void InitializeComponent()
{
// ... (Order of statements is same as in actual code) ...
this.tpFpA = new System.Windows.Forms.TabPage();
this.fpInfoA = new ResearchTool.FPInfo();
// ...
this.tpFpA.Controls.Add(this.fpInfoA); // THIS LINE BLOWS UP IN DESIGN MODE
}
关于如何追查此问题的想法?例如,有没有办法调试设计器的初始化?
答案 0 :(得分:5)
如果您无法解决问题,可采用一种解决方法,即使用DesignMode
检查来包围有问题的代码。
如:
private void InitializeComponent()
{
...
if(!DesignMode)
{
this.fpInfoA = new ResearchTool.FPInfo();
}
...
}
如果它在设计模式中不需要并且速度非常慢,比如连接到数据库或类似的东西,这也可以加快它的速度。
答案 1 :(得分:1)
您可以在以下位置找到有关如何跟踪设计时代码执行的信息:
What information do you need to fix a problem, which occurs with your products at design time?
答案 2 :(得分:0)
As Hans Olsson said,可以通过检查设计模式和禁用违规逻辑来解决这个问题。
如果UserControl
的构造函数出现任何问题,也会触发此错误。如果设计器实例化UserControl
时出现异常,则设计器将失败。在我的情况下,失败导致相同的" [...]要么未声明,要么从未被分配" 错误。
例如,请参阅以下用户控件:
public class MyUserControl : UserControl {
public MyUserControl()
{
InitializeComponent();
throw new Exception(); //Causes a designer error.
}
}
现在,在观察设计人员包含此MyUserControl
的表单时,我们会看到类似于以下内容的内容:
我不能说设计师对于以前版本的Visual Studio是否是这样的;但对于Visual Studio 2017,您可以清楚地看到发生了什么。
设计师失败了,因为抛出了System.Exception
。因此,实际上自动生成的设计器代码是正确的,变量[REDACTED]
被认为是未声明的或从未分配过。问题在于MyUserControl
的构造函数。
现在,如果您需要在控件的构造函数中放置依赖于外部服务/资源的逻辑,您需要指出它应该只在运行时发生。或者,您可以为设计时提供模拟资源。
为此,您可以use the LicenseManager
and check its current UsageMode
。
下面修改过的代码现在只在运行时抛出异常,设计者不再有错误了。
public class MyUserControl : UserControl {
public MyUserControl()
{
InitializeComponent();
if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
{
throw new Exception(); //No longer fails in design-time.
}
}
}