Есть ли событие, которое я могу использовать, чтобы определить, была ли дочерняя форма добавлена или удалена из родителя MDI?
Добавлено или удалено определение формы MDI с дочерней формой
Ответы (7)
Нет, нет. Вам нужно будет создать подкласс Form и предоставить определенные события, которые укажут, когда будет добавлен дочерний элемент, а затем направить все вложения дочерних форм через метод, который подключит дочернюю форму, а также вызовет событие.
Да. В основной форме MDI подключитесь к событию MdiChildActivated.
Вот так:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.MdiChildActivate += new EventHandler(Form1_MdiChildActivate);
}
void Form1_MdiChildActivate(object sender, EventArgs e)
{
MessageBox.Show("Activated");
}
private void addToolStripMenuItem_Click(object sender, EventArgs e)
{
Form form2 = new Form2();
form2.MdiParent = this;
form2.Show();
}
}
И это событие сработает, когда дочерняя форма активируется или деактивируется.
Подключите событие MdiChildActivate
и сохраните список распознанных детей. Когда активируется новая форма, также подключите событие FormClosed
.
private List<Form> ChildFormList = new List<Form>();
private void MyForm_MdiChildActivate(object sender, EventArgs e)
{
Form f = this.ActiveMdiChild;
if (f == null)
{
//the last child form was just closed
return;
}
if (!ChildFormList.Contains(f))
{
//a new child form was created
ChildFormList.Add(f);
f.FormClosed += new FormClosedEventHandler(ChildFormClosed);
}
else
{
//activated existing form
}
}
private void ChildFormClosed(object sender, FormClosedEventArgs e)
{
//a child form was closed
Form f = (Form)sender;
ChildFormList.Remove(f);
}
Я понял, что это слишком поздно, однако, поскольку ответы здесь помогли мне решить эту проблему, я бы упомянул, что это отлично работает с использованием массива MdiChildren в .net 4. Единственное, что вам нужно сделать, это проверить, удаляется ли форма или удаляется чтобы сказать, закрывается ли он.
ie:
private void frmContainer_MdiChildActivate(object sender, EventArgs e)
{
tabWindows.RefreshLayout(this.MdiChildren.ToList());
}
public void RefreshLayout(List<Form> forms)
{
this.nextButtonLeft = 1;
panel1.Controls.Clear();
foreach (Form frm in forms)
{
if (!(frm.Disposing || frm.IsDisposed)) { addButton(frm); }
}
}
Да, вы можете легко обнаружить добавление форм в MDI Form.
Если пометить ParentForm как MdiContainer, задав для IsMdiContainer значение true, возникнет событие ParentForm.ControlAdded для добавления элемента управления "MdiClient" в родительскую форму. Таким образом, при добавлении MdiClient в родительскую форму MDI мы можем сгенерировать событие ControlAdded для элемента управления MdiClient, как показано ниже:
public ParentForm()
{
InitializeComponent();
this.ControlAdded += Form1_ControlAdded;
this.IsMdiContainer = true;
Нам нужно поднять MdiClient.ControlAdded, как показано ниже:
void Form1_ControlAdded(object sender, ControlEventArgs e)
{
if(e.Control is MdiClient)
e.Control.ControlAdded += MdiClient_ControlAdded;
}
По умолчанию дочерние формы MDI добавляются в коллекцию элементов управления MdiClient в родительской форме. Таким образом, при установке значения ChildForm.MdiParent в качестве родительской формы возникает событие ControlAdded для MdiClient.
void MdiClient_ControlAdded(object sender, ControlEventArgs e)
{
}
Таким образом, используя описанный выше метод, вы можете узнать, какие дочерние формы MDI добавлены в родительские формы MDI. Таким образом, вы можете добавить событие ControlRemoved для элемента управления MdiClient, чтобы узнать, какие дочерние формы удалены из формы MDI.
Надеюсь, что это поможет вам.
Поскольку событие MdiChildActivate запускается до того, как дочерняя форма MDI фактически закрывается, и, следовательно, недостаточно информации, чтобы определить, действительно ли дочерняя форма MDI активирована или закрыта, я выбрал другой подход для решения проблемы.
Я обнаружил, что событие ParentChanged срабатывает в дочерней форме MDI, когда она закрыта.
public class MdiParentForm : Form
{
// ...
private Form CreateMdiChildForm()
{
var form = new MdiChildForm
form.ParentChanged += MdiFormParentChangedHandler;
form.MdiParent = this;
return form;
}
private void MdiFormParentChangedHandler(object sender, EventArgs args)
{
var form = sender as Form;
if (form != null)
{
if (form.MdiParent != null)
{
// MDI child form will activate
// ... your code here
}
else
{
// MDI child form will close
form.ParentChanged -= MdiFormParentChangedHandler;
// ... your code here
}
}
}
// ...
}
Недавно я хотел примерно определить, когда не было открытых MDI-детей, чтобы я мог отображать панель с множеством кнопок «что делать» только тогда, когда не было открытых дочерних форм. (просто исследую дизайнерскую идею).
Мое окончательное решение было элегантно простым — добавить таймер в родительскую форму и запускать таймер каждый раз, когда событие MdiChildActivate определяет, что открыта 1 дочерняя форма.
private void MyForm_MdiChildActivate(object sender, EventArgs e)
{
this.panel_Tools.Visible = false;
if (this.MdiChildren.Count() == 1)
{
this.timer_WindowsCounter.Start();
}
else
{
this.timer_WindowsCounter.Stop();
}
}
private void timer_WindowsCounter_Tick(object sender, EventArgs e)
{
if (this.MdiChildren.Count() == 0)
{
this.panel_Tools.Visible = true;
this.timer_WindowsCounter.Stop();
}
}