Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Вызов дочернего окно в родительском


Автор: Ali002 14.4.2014, 17:34
Программисты! Тут такое дело есть родительское окно а есть дочернее, при нажатии на кнопку дочернего окна, которое отркылось в родительском окне, должно выходить другое дочернее окно в этом же родительском окне, так как это реализовать?
  Вот код открытия дочернего окна в родительском пытаюсь сделать так же на третьей форме не получается так как это сделать?


Код

bool fopen = false;
            foreach (Form f in this.MdiChildren)
            {
                if (f is Form11)
                {
                    f.Focus();
                    fopen = true;
                }
            }
            if (fopen == false)
            {
                Form11 f = new Form11();
                f.MdiParent = this;
                f.Show();
            }

Автор: micronic 16.4.2014, 15:29
Вся суть задачи заключается в том, чтобы присвоить свойству MdiParent дочернего окна указатель на родительское окно. Сделать это можно кучей способов...

1. Используя MdiParent дочернего окна #1, которое вызывает дочернее окно #2.

Код

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2(null);
            form2.MdiParent = this.MdiParent;
            form2.Show();
        }

Я специально привел данный код в обработчике кнопки. Данный код можно использовать не везде. Ведь если посмотреть, как мы вызываем дочернюю форму в MainForm
Код

                Form11 f = new Form11();
                f.MdiParent = this;
                f.Show();

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

2. Передавая указатель на MainForm дочерней форме

Мы всегда можем модифицировать конструктор дочерней формы таким образом
Код

        public Form2(Form parentForm)
        {
            InitializeComponent();
        }

Тогда создание дочерней формы в MainForm будет таким
Код

                Form11 f = new Form11(this);
                f.MdiParent = this;
                f.Show();

Теперь у нас есть указатель на MainForm даже в конструкторе дочерней формы.

3. Можно оставить возможность создавать дочерние формы исключительно в MainForm

Мне кажется данный способ наиболее идеологически верным. Тем более что в MDI-приложениях часто при создании дочернего элемента MainForm должна произвести кучу дополнительных служебных действий (добавить вкладку на панель вкладок, изменить цвета где-нибудь и т.п.).
Логика следующая... Дочерняя форма должна отправить родительской команду на создание нового элемента. А родительская уже будет делать всю грязную работу. Для этого удобно использовать события.

Создаем событие в коде дочернего окна. В этот момент мы определяем, какие параметры будут передаваться нашему событию... Полезно передать указатель на дочернюю форму, потому что иначе MainForm не будет знать, какое именно дочернее окно запросило создание нового (а это скорее всего важная информация), плюс ко всему по этому указателю можно будет обратиться к любому элементу дочерней формы.
Код

        public delegate void MakeNewFormEvent(Form2 sender);
        private MakeNewFormEvent _MakeNewForm;

        public event MakeNewFormEvent MakeNewForm
        {
            add { _MakeNewForm += value; }
            remove { _MakeNewForm -= value; }
        }

Теперь из MainForm мы можем прицепить к этому событию свой обработчик, который будет создавать новое окно тогда, когда будет вызываться данное событие
Код

            ...
                Form11 f = new Form11();
                f.MdiParent = this;
                f.MakeNewForm += new Form11.MakeNewFormEvent(makeNewForm);
                f.Show();
            ...

            private void makeNewForm(Form2 sender)
            {
                Form11 f = new Form11();
                f.MdiParent = this;
                f.MakeNewForm += new Form11.MakeNewFormEvent(makeNewForm);
                f.Show();
            }

Обработчик makeNewForm помимо того что создает новое дочернее окно - сразу цепляет к нему себя же, чтобы новое созданное окно так же могло отправлять команду на создание себе подобных.
Сама же подача сигнала из дочерней формы вызывается достаточно просто:
Код

        private void button1_Click(object sender, EventArgs e)
        {
            _MakeNewForm(this);
        }


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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)