我的目标是响应mdi容器关闭的最后一个子窗体(例如,关闭父本身或显示新内容)。我面临的问题是mdi容器的MdiChildren集合仍然表明容器包含子容器。
我尝试的方法是
void childMdiForm_FormClosed(object sender, FormClosedEventArgs e)
{
if (this.MdiChildren.Any())
{
//Do stuff
}
}
最后一个子表单关闭后, MdiChildren.Count()
仍为1。
尝试处理parentform.MdiChildActivate
事件时,我的结果相同。
当子表单关闭时,MdiChildren
集合似乎尚未更新。当有多个孩子时会发生同样的情况:它仍然包含所有的孩子,它似乎会在稍后更新集合。
这是正确的做法吗?如果没有,我怎样才能在关闭表格后准确计算mdi孩子的数量?
答案 0 :(得分:3)
是的,在传递FormClosed事件之后,MdiChildren属性才会更新。对于像这样的事件顺序问题,有一个通用的解决方案,您可以通过使用Control.BeginInvoke()方法优雅地获取在事件处理完成后运行的代码。此代码解决了您的问题:
protected override void OnMdiChildActivate(EventArgs e) {
base.OnMdiChildActivate(e);
this.BeginInvoke(new Action(() => {
if (this.MdiChildren.Length == 0) {
// Do your stuff
//...
MessageBox.Show("None left");
}
}));
}
答案 1 :(得分:2)
WinForms有时会有点古怪,这就是一个例子。我不完全确定为什么关闭最后一个MDI子项不会使MdiChildren
属性立即返回一个空数组。
在大多数情况下,您将自己跟踪子窗体或数据模型,因此我只需保留一个本地阵列来管理它:
List<Form> childForms = new List<Form>();
void AddChildWindow()
{
var window = new ChildForm();
window.MdiParent = this;
window.Tag = Guid.NewGuid();
window.FormClosed += (sender, e) => { OnMdiChildClosed(sender as Form, e.CloseReason); };
window.Shown += (sender, e) => { OnMdiChildShown(sender as Form); };
window.Show();
}
void OnMdiChildShown(Form window)
{
childForms.Add(window);
Trace.WriteLine(string.Format("Child form shown: {0}", window.Tag));
Trace.WriteLine(string.Format("Number of MDI children: {0}", childForms.Count));
}
void OnMdiChildClosed(Form window, CloseReason reason)
{
childForms.Remove(window);
Trace.WriteLine(string.Format("Child form closed: {0} (reason: {1})", window.Tag, reason));
Trace.WriteLine(string.Format("Number of MDI children: {0}", childForms.Count));
if (childForms.Count == 0)
{
// Do your logic here.
}
}
答案 2 :(得分:1)
这是一个完整的测试示例:
namespace WindowsFormsApplication1
{
public partial class mdiMainForm : Form
{
private List<Form> _children = new List<Form>();
public mdiMainForm()
{
InitializeComponent();
}
private void mdiMainForm_Shown(Object sender, EventArgs e)
{
Form3 f3 = new Form3();
f3.MdiParent = this;
f3.FormClosed += mdiChildClosed;
_children.Add(f3);
f3.Show();
Form4 f4 = new Form4();
f4.MdiParent = this;
f4.FormClosed += mdiChildClosed;
_children.Add(f4);
f4.Show();
Form5 f5 = new Form5();
f5.MdiParent = this;
f5.FormClosed += mdiChildClosed;
_children.Add(f5);
f5.Show();
}
private void mdiChildClosed(Object sender, FormClosedEventArgs e)
{
if (_children.Contains((Form)sender))
_children.Remove((Form)sender);
if (_children.Count == 0)
MessageBox.Show("all closed");
}
}
}
答案 3 :(得分:0)
您的代码似乎暗示您正在检查子Form的MdiChildren集合。但也许我误读了你的代码。
使用MDI表单的'MdiChildActivate'事件:
private void Form1_MdiChildActivate(object sender, EventArgs e) {
if(this.MdiChildren.Length == 0) {
// replace with your "Do Stuff" code
MessageBox.Show("All Gone");
}
}
答案 4 :(得分:0)
我知道这个答案很晚,但我对这个问题的解决方案要比提供的解决方案简单得多,所以我会在这里分享。
$allowedTypes = ['video', 'image', 'audio'];
...
if ( in_array(
explode("/",
mime_content_type($_FILES['fileToUpload1']["tmp_name"][$counter])
)[0],
$allowedTypes) )