Конструктор Visual Studio WinForms не создает экземпляр объекта

Я создал класс, производный от класса System.Windows.Forms.ContextMenuStrip, не как пользовательский элемент управления, а просто простой класс .cs с конструктором и одним обработчиком событий.

Когда я перетаскиваю этот класс из панели инструментов в конструктор, он создает для него закрытый член и несколько свойств, но не создает экземпляр объекта.

Таким образом, во время выполнения я получаю «Ссылка на объект не установлена ​​на экземпляр объекта», потому что дизайнер никогда не генерирует строку:

this.searchGridContextMenu1 = новое SearchGridContextMenu ();

внутри InitializeComponent.

Раньше он генерировал эту строку, на самом деле, я продолжаю вставлять ее обратно из своего репозитория Vault, но дизайнер просто снова ее "съедает".

Обновление: теперь я попытался создать пользовательский элемент управления с использованием того же класса, и при этом возникла та же проблема.


person Dennis    schedule 04.02.2009    source источник
comment
Я пока не нашел решения этого. А пока я делаю вручную то, чем не занимается дизайнер.   -  person Dennis    schedule 11.02.2009


Ответы (5)


Я разместил этот комментарий по другому вопросу, но, поскольку это связано здесь, это снова.

Когда пользовательский элемент управления не загружается в конструктор 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. Это откроет диалоговое окно исключений. Установите флажок в столбце THROWN рядом с «Исключениями среды CLR».

ПРИМЕЧАНИЕ. Это гарантирует, что INSTANCE_1 будет ПРЕРЫВАТЬ при ЛЮБОЙ ошибке времени выполнения, даже если он попадет в блок попытки.

  1. Переключитесь на INSTANCE_2. В обозревателе решений дважды щелкните, чтобы открыть ошибочный пользовательский элемент управления.

Вы должны обнаружить, что INSTANCE_1 OF Visual Studio должен был остановиться на строке кода, из-за которой конструктор не загружал элемент управления. Исправьте код (что обычно означает тестирование IsNot Nothing перед ссылками на свойства объекта ... но может означать и другие вещи.)

Кроме того, иногда я обнаруживаю, что элемент управления БУДЕТ загружаться в INSTANCE_2 вместо того, чтобы прерывать ошибку в INSTANCE_1. В этом случае просто прекратите отладку ... закройте INSTANCE_2. Сохраните / перезапустите INSTANCE_1, и ваша проблема часто исчезнет.

Урок такой. Пользовательский элемент управления ДОЛЖЕН иметь возможность загружать / ссылаться на все объекты и их элементы, чтобы загрузить их в конструктор. Поэтому для пользовательских элементов управления, которые будут помещены в другие контейнеры, я обычно создаю события для уведомления родительского элемента, а не пытаюсь протолкнуть объекты в дочерний элемент управления.

Надеюсь, это поможет в будущем справиться с этим старым вопросом.

Сет

person Seth Spearman    schedule 03.06.2009
comment
+1 за перезапуск Visual Studio. Дизайнер WinForms иногда путается - person Pedro; 29.06.2010
comment
Я не мог создать собственный пользовательский элемент управления в конструкторе winforms. Я попытался перезапустить, очистить, перестроить, запустить от имени администратора и т. Д. Я попробовал это, так как решил, что это должно быть ошибка с моей стороны, хотя раньше она работала. Как только я запустил его таким образом, моя проблема исчезла, и ошибки не было обнаружено. Джимми, рождество, какими иногда могут быть кластерные winforms. - person VoteCoffee; 17.06.2018

Я правильно прочитал? Visual Studio удаляет строку, которая создает экземпляр вашего элемента управления?

Ваш конструктор общедоступен? В какой-то момент я изменил доступность моего конструктора с общедоступной на внутреннюю - пытаясь быть хорошим, не позволять надоедливым пользователям получать доступ к тому, чего они не должны, - но потом я страдал от тех же эффектов, которые вы описываете, мне все время приходилось добавлять свои конструктор обратно в InitializeComponent.

Мне потребовались месяцы, чтобы осознать свою ошибку ... я просто продолжал думать, что это ошибка в Visual Studio. Поменял обратно на общедоступный и никаких проблем.

person nopskazoid    schedule 13.07.2011
comment
У меня была точно такая же проблема, и после нескольких часов устранения неполадок я наткнулся на этот пост. Ты спасатель! - person Jon Tackabury; 15.06.2012

Наследования от элемента управления недостаточно. Это минимум, который мне пришлось реализовать, чтобы он заработал:

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
    }
}
person OJ.    schedule 04.02.2009
comment
Похоже, это не повлияет на поведение. - person Dennis; 05.02.2009

Эта проблема возникает, когда InitializeComponent () пересекается с базовыми и унаследованными компонентами. Решение - вызвать метод конструктора компонента. В противном случае будет вызван базовый метод.

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

изменение моего конструктора без параметров с внутреннего на общедоступное решило проблему

person FanTasteYou    schedule 29.08.2018