Унаследованная форма.NET (WinForms) - проблема дизайнера VS

У меня есть несколько форм в приложении C#. Я использую Visual Studio 2010 Beta, но.NET 3.5 и C# 3.

У меня есть базовая форма, называемая FilteredQueryViewForm в пространстве имен Shd, и я хочу, чтобы некоторые другие формы наследовали ее (потому что они в основном будут делать то же самое, но с некоторыми дополнениями).

Я изменил вещи с закрытых на защищенные в классе FilteredQueryViewForm, чтобы они были доступны из производных форм. После этого я создал производную форму и установил базовый класс в FilteredQueryViewForm.

Дизайнер производного класса жаловался на то, что Shd.FilteredQueryViewForm не имеет конструкторов... независимо от того, есть ли у него один, с 3 параметрами. Я думал, что параметры могут быть проблемой, поэтому я также создал (общедоступный) конструктор без параметров, но он все еще не работает. Сообщение об ошибке то же самое:

"Конструктор типа Shd.FilteredQueryViewForm не найден."

И конструктор производного класса не будет загружаться. Я попытался перезапустить vs2010beta, воссоздав производную форму, но ничего не помогло. Google не дал мне никаких полезных результатов по этой проблеме.:(

Это проблема Visual Studio 2010 Beta? Или я что-то не так делаю?

6 ответов

Решение

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

Проблема заключается в том, что если вы создаете форму, которая наследуется от Shd.FilteredQueryViewForm, дизайнер попытается вызвать конструктор родительской формы, но он загружает эту форму не из кода, а из встроенной сборки.

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

Эмисвельт говорит: "Вам понадобится конструктор без параметров, который вызывает метод InitializeComponent() во всех ваших формах". Это на самом деле не нужно. Вы можете объявить пользовательский параметризованный конструктор в производной форме и обычно вызывать метод InitializeComponent (также с вызовом пользовательского конструктора). Важно то, что ваш конструктор вызывает "InitializeComponent" (для новых элементов управления), а базовый конструктор вызывает "InitializeComponent" (для унаследованных компонентов). Эта ситуация будет работать во время выполнения, но вы не увидите унаследованные элементы управления в конструкторе Visual Studio. Чтобы показать все элементы управления во время разработки, вы должны добавить только простой конструктор без параметров в базовом классе.

Например, если ваша база - это форма с кнопкой и двумя переключателями:

using System.Windows.Forms;
namespace Test
{
    public partial class Form1 : Form
    {
        public Form1(string foo)
        {
            //use "foo" here
            InitializeComponent(); //here button and radios will be initialized
        }
    }
}

Вы можете увидеть это в инструменте дизайна, и вы можете избежать пустого конструктора (без параметров) без проблем. Форма Form2 теперь унаследована от Form1:

namespace Test
{
    public partial class Form2 : Form1
    {
        public Form2(string foo) : base(foo)
        {
            //you can use "foo" here even if it is passed to base class too
            InitializeComponent();
        }
    }
}

Пустого конструктора нет, и он будет компилироваться и работать нормально. В rutime ваша Form2 покажет тот же набор элементов управления, что и Form1. Но... вы не можете видеть это во время разработки, потому что Visual Studio не может определить, где находится метод InitializeComponent, и отображается ошибка. Зачем? Потому что где-то в цепочке вызовов должен быть конструктор без параметров. Решение представляет собой простую модификацию базового класса:

using System.Windows.Forms;

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1(string foo):base()
        {
           //use foo here
        }

        public Form1()         //Visual studio designer likes this!
        {
            InitializeComponent();
        }
    }
}

Это все.

Я думаю, вы имели в виду, что ваш Form1.cs [дизайн] не обновлялся, когда вы добавляли базовый класс. У меня такая же проблема. Как ни странно, программа будет работать нормально, когда вы нажмете "Пуск", и вы увидите компоненты вашего базового класса в вашей Форме, когда вы ее запустите, но не когда вы находитесь в режиме редактирования.

Просто дважды щелкните Form1.cs в обозревателе решений. Это сработало для меня.Сделай это

Убедитесь, что базовая форма (формы) определены в сборке, которая скомпилирована с использованием параметра сборки AnyCPU.

Я пробовал все другие ответы, но в моем случае проблема была в свойствах проекта. (Я экспериментировал с новым проектом WinForms по умолчанию)

  1. Открыть свойства проекта (проект -> свойства -> Сборка)Открыть свойства
  2. Установите для параметра «Цель платформы» значение «Любой процессор». Установите платформу.
  3. Наследовать класс Form2 от класса Form1 Наследовать
  4. Перестроить проект Перестроить

мой проект находится на целевой платформе .NET Framework 4.7.1

Это все.

У меня была аналогичная проблема с другим исключением, связанным с кодом в методе _Load моей базовой формы, поэтому ни одно из решений мне не помогло. Во время разработки было исключение, которое не происходит во время выполнения (нулевое значение, относящееся к статическому экземпляру другого класса). Мое решение заключалось в том, чтобы поместить блок try-catch вокруг всего кода этого метода.

Другие вопросы по тегам