Унаследованная форма .NET (WinForms) - проблема дизайнера VS - PullRequest
8 голосов
/ 01 августа 2009

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

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

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

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

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

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

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

Ответы [ 3 ]

21 голосов
/ 01 августа 2009

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

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

2 голосов
/ 30 июля 2015

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

Emiswelt говорит: «Вам понадобится конструктор без параметров, который вызывает метод 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();
        }
    }
}

Вот и все.

1 голос
/ 02 апреля 2015

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

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

...