Унаследованная форма.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 по умолчанию)
- Открыть свойства проекта (проект -> свойства -> Сборка)Открыть свойства
- Установите для параметра «Цель платформы» значение «Любой процессор». Установите платформу.
- Наследовать класс Form2 от класса Form1 Наследовать
- Перестроить проект Перестроить
мой проект находится на целевой платформе .NET Framework 4.7.1
Это все.
У меня была аналогичная проблема с другим исключением, связанным с кодом в методе _Load моей базовой формы, поэтому ни одно из решений мне не помогло. Во время разработки было исключение, которое не происходит во время выполнения (нулевое значение, относящееся к статическому экземпляру другого класса). Мое решение заключалось в том, чтобы поместить блок try-catch вокруг всего кода этого метода.