Visual Studio WinForms设计器不实例化对象

我创建了一个派生自System.Windows.Forms.ContextMenuStrip类的类,而不是用户控件,只是一个带有构造函数和一个事件处理程序的普通.cs类。

当我将这个类从工具箱拖到设计器上时,它会为它创建一个私有成员和几个属性,但不会实例化一个对象。

因此,在运行时我得到“对象引用未设置为对象的实例。”,因为设计者从不生成该行:

this.searchGridContextMenu1 = new SearchGridContextMenu();

在InitializeComponent中。

它曾用于生成这一行,事实上,我一直把它从我的Vault存储库中重新插入,但设计师只是“再次”使用它。

更新:我现在尝试使用相同的类创建用户控件,它只是这样做有同样的问题。

我在另一个问题上交叉发表了这条评论,但由于这与此相关,因此它又是。

当用户控件无法加载到Visual Studio设计器中时,您需要执行此操作。 这些指令适用于vb.net项目,但c#应该类似。 此外,在此之前关闭所有打开的窗口(或至少您正在处理的控件的源和设计器文件。)

最后一件事。 您应该做的第一件事是确保重新启动visual studio不能解决问题。 如果没有,您可以尝试以下步骤。 这些说明假定错误的用户控件位于visual studio中的控件库项目中。 如果没有,你应该能够稍微调整方向以使其工作,但是当控件在自己的项目中时更容易。

请执行下列操作:

  1. 使控件库成为您的启动项目。
  2. 打开控件库项目的属性,然后单击调试选项卡。
  3. 在“开始操作”下,单击“启动外部程序”选项并浏览到Visual Studio可执行文件。

注意:这意味着当您运行解决方案时,它将启动另一个Visual Studio实例,而不是实际运行您的解决方案。 Visual Studion的第一个实例(INSTANCE_1)将在您运行时“托管”Visual Studio的第二个实例(INSTANCE_2)。

  1. 运行您的解决方案 INSTANCE_2将加载。
  2. 切换回INSTANCE_1。
  3. 在INSTANCE_1中按CTRL-ALT-E。 这将打开例外对话框。 选中Common Language Runtime Exceptions旁边的THROWN列复选框。

注意:这将确保INSTANCE_1在任何运行时错误都会发生故障,即使它在try块中命中也是如此。

  1. 切换到INSTANCE_2。 在解决方案资源管理器中,双击以打开错误的用户控件。

您应该会发现,INSTANCE_1 OF Visual Studio应停止在导致设计器无法加载控件的代码行中。 修复代码(这通常意味着在引用对象属性之前测试IsNot Nothing ……但可能意味着其他事情。)

此外,有时我发现控件将在INSTANCE_2中加载,而不是在INSTANCE_1中打破错误。 在这种情况下,只需停止调试…关闭INSTANCE_2。 保存/重新启动INSTANCE_1,您的问题通常会消失。

教训就是这样。 用户控件必须能够加载/引用所有对象及其成员,以便将其加载到设计器中。 因此,对于将放置在其他容器上的用户控件,我通常会设计事件来通知父级而不是尝试将对象推送到子控件中。

希望这有助于将来参考这个老问题。

赛斯

我读过这个吗? Visual Studio是否删除构造控件实例的行?

你的构造函数是公开的吗? 在某些时候,我将构造函数的可访问性从公共更改为内部 – 试图变得更好,阻止讨厌的用户访问他们不应该访问的东西 – 但后来我遭受了与您描述的相同的影响,我不得不添加我的构造函数回到InitializeComponent。

我花了几个月才意识到自己的错误……只是一直认为这是Visual Studio中的一个错误。 将其更改回公众并没有问题。

inheritance控制是不够的。 这是我必须实现的最低限度才能使其工作:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace WinForms { class Foo : System.Windows.Forms.ContextMenuStrip { public Foo() { InitializeComponent(); } protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); } ///  /// Required designer variable. ///  private System.ComponentModel.IContainer components = null; ///  /// Clean up any resources being used. ///  /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code ///  /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///  private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion } } 

当InitializeComponent()与基本和inheritance的组件交叉时,会发生此问题。 解决方案是调用组件的设计者方法。 否则将调用基本方法。

 public Form() { this.InitializeComponent(); // base.InitializeComponent <-- default one is thisone } 

将无参数构造函数从内部更改为公共已解决了该问题