3

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

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

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

this.searchGridContextMenu1 = new SearchGridContextMenu();

内部初始化组件。

它曾经生成这条线,事实上,我一直把它从我的 Vault 存储库放回去,但设计师只是再次“吃掉它”。

更新:我现在尝试使用同一个类创建一个用户控件,但这样做也有同样的问题。

4

5 回答 5

6

我在另一个问题上交叉发布了此评论,但由于这与此处相关,因此再次出现。

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

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

请执行下列操作:

  1. 使控件库成为您的启动项目。
  2. 打开控件库项目的属性,然后单击调试选项卡。
  3. 在 Start Action 下单击 Start external program 选项并浏览到 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,您的问题通常会消失。

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

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

赛斯

于 2009-06-03T20:25:27.623 回答
4

我没看错吗?Visual Studio 删除构造控件实例的行?

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

我花了几个月的时间才意识到我的错误……只是一直认为这是 Visual Studio 中的一个错误。改回public,没有问题。

于 2011-07-13T11:03:45.190 回答
1

从控件继承是不够的。这是我必须实施以使其工作的最低要求:

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);
        }

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }

        #endregion
    }
}
于 2009-02-04T23:22:53.353 回答
1

This problem occurs when InitializeComponent () crosses with base and inherited components. Solution is call the component's designer's method. Otherwise the base method will be called.

public Form()
{
    this.InitializeComponent(); 
    // base.InitializeComponent <-- default one is thisone
}
于 2010-02-15T13:00:21.847 回答
0

将我的无参数构造函数从内部更改为公共已经解决了这个问题

于 2018-08-29T09:44:36.090 回答