我有一个有趣的问题..
我有一个Form通过Button启动另一个Form(2)。在Form2关闭之前,它有时会触发一个使表单1无效的事件并强制表单1刷新它的数据。我遇到的问题是在表单2触发事件后,表单1似乎得到它并处理它,并刷新它的数据并且只有表单2关闭。我希望Form 2触发事件并关闭,在Form1的事件处理程序捕获并处理事件之前。
我觉得它与BackgroundWorker
有点相似(有点像Java中的SwingUtilities.InvokeLater)..但我对它没有经验......
public class Frm1{
void LaunchForm2(){
Frm2 form2 = new Frm2();
form2.dataChanged += new DataChangeListener(myListener);
form2.showDialog();
}
private void myListener(){
//get my data again
}
}
public class Frm2{
private void Close(){
if(myDataHasChanged){
if(dataChanged != null) {
dataChanged();
}
this.Close();
}
}
}
答案 0 :(得分:2)
您是否有在这种情况下使用事件的具体原因?
在Form2上公开一个属性,允许您检查数据是否已更改。 ShowDialog()调用返回后,检查属性的值并在必要时进行更新。
(编辑删除我现在无用的代码示例。)
答案 1 :(得分:2)
您可以在OnHandleDestroyed中执行此操作,因为它在最终销毁窗口句柄后完成。你可以肯定:
因此执行以下操作:
public class Frm2 : Form
{
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
if (myDataHasChanged)
{
if (dataChanged != null)
dataChanged();
}
}
private void Close()
{
if (myDataHasChanged)
this.Close();
}
}
更新:
测试以验证在从ShowDialog()返回之前调用HandleDisposed:
bool called = false;
Form test = new Form();
test.Shown += delegate (Object o, EventArgs e) { test.Close(); };
test.HandleDestroyed += delegate(Object o, EventArgs e) { called = true; };
test.ShowDialog();
Assert.IsTrue(called);
答案 2 :(得分:0)
为什么不在form2的Closed事件中引发DataChanged事件?
答案 3 :(得分:0)
您可以在致电Close
后举起活动 - 调用Form.Close
不会退出调用它的方法。
编辑:在处理事件之前尝试使用BeginInvoke
等待下一个消息循环,如下所示:
form2.dataChanged += delegate { BeginInvoke(new DataChangeListener(myListener)); };
2 nd 编辑:为了给Form1一个重绘的机会,在更新前调用BeginInvoke两次等待两个消息循环(一个关闭Form2,另一个关闭重绘Form1),像这样:
form2.dataChanged += delegate(parameters) {
BeginInvoke(new Action(delegate {
BeginInvoke(new DataChangeListener(myListener), parameters);
}));
//Or,
BeginInvoke(new Func<Delegate, object[], IAsyncResult>(BeginInvoke),
new object[] { parameters }
);
};
答案 4 :(得分:-1)
尝试将事件调用更改为:
public class Frm2{
private void Close(){
if(myDataHasChanged){
if(dataChanged != null) {
dataChanged.BeginInvoke();
}
this.Close();
}
}
}
这不保证在myListener()完成之前表单关闭。但是,它应该允许表单关闭而不等待myListener()完成。