C# parent-child 往返 Close() 无法正常工作,但 Hide() 可以
C# parent-child round trip Close() not working properly but Hide() does
我正在开发 C# console/winforms 桌面应用程序。它监视一些本地驱动器属性,并通过任务计划程序按用户定义的计划显示状态消息。用户可以保存多个时间表。以下是对 select/activate 特定保存的时间表采取的操作(屏幕截图的大小为 50% 并合并为一个图形):
- 屏幕截图 A:单击“更改活动”按钮调用 child 表单
- 屏幕截图 B:select 来自组合框的计划并单击激活
关闭 child 表单的选定计划,传递 selected
处理时间表。
- 屏幕截图 C – 使用 Close() 方法的结果:
计划定义屏幕填充了 selected
日程安排的详细信息,包括(如果需要)调用不同的 child
形成但 select 活动计划表实际上并未关闭
在 parent 表单开始处理填充数据之前;仅在通过单击“保存”或“取消”关闭 Child2 后,Child1 才会关闭。
- 屏幕截图 D – 使用 Hide() 方法的结果:按预期工作
相关代码(我认为)
public interface IselectSchedule
{
void SelectSchedule(string sName);
}
/// Parent form
public partial class DefineSched : Form, IDates, IDoWs, IselectSchedule
{
/// calling Child1
private void ChangeActvLBLasBTN_Click(Object sender, EventArgs e)
{
SetActvSchedule callSetActvSched = new SetActvSchedule(this);
callSetActvSched.StartPosition = FormStartPosition.Manual;
callSetActvSched.Location = new Point(this.Left + 45, this.Top + 25);
callSetActvSched.ShowDialog();
}
}
/// Child1 form
public partial class SetActvSchedule : Form
{
IselectSchedule _callingForm;
public SetActvSchedule(IselectSchedule caller)
{
InitializeComponent();
_callingForm = caller;
}
/// form content
private void SaveBTN_Click(Object sender, EventArgs e)
{
this.Close(); // not achieving my objective but Hide does
_callingForm.SelectSchedule(_sname);
}
}
/// back in Parent form
public void SelectSchedule(string sName)
{
_sName = sName;
bool useDB = false;
SetActvDisplay(useDB);
EditSaved(useDB);
}
private void EditSaved(bool useDB)
{
/// populate parent form data & call Child2
SelectDoW callSelectDoWs = new SelectDoW(this, det, det2);
callSelectDoWs.StartPosition = FormStartPosition.CenterParent;
callSelectDoWs.ShowDialog(owner: this);
/// ready for editing
我已经 researched/understand 决定隐藏还是关闭,我认为关闭在这里是合适的。我的问题是,既然 Close() 先于返回到 parent 表单,为什么在 parent 表单开始处理传递的信息之前该操作没有完成?
提前感谢您的任何见解。
虽然我相信我几乎可以使用上面建议的多线程方法,但我 运行 遇到了一个我无法解决的跨线程错误。经过进一步考虑,我可能一直在寻求一个不必要的复杂解决方案来实现一个非常简单的 objective;向用户提供一些选项并根据他们的选择采取行动。
简单的解决方案是在子表单中设置的父表单中的 public 静态字段,之后子表单完全关闭并控制 returns 到父表单:
/// Parent form
public partial class DefineSched : Form
{
public static string _sName;
/// calling Child
private void ChangeActvBTN_Click(Object sender, EventArgs e)
{
SetActvSchedule callSetActvSched = new SetActvSchedule();
callSetActvSched.ShowDialog();
ActvSchedOptions();
}
}
/// Child1 form
public partial class SetActvSchedule : Form
{
private void SaveBTN_Click(Object sender, EventArgs e)
{
DefineSched._sName = _sname;
this.Close();
}
}
/// back in Parent form
ActvSchedOptions()
{
/// series of conditional statements
这种方法避免了对接口的需要,并避免了 UI 线程过载。我怀疑它不会被认为是一个特别优雅的解决方案,但它有一个可取之处:它可以完美地完成手头的任务。
我正在开发 C# console/winforms 桌面应用程序。它监视一些本地驱动器属性,并通过任务计划程序按用户定义的计划显示状态消息。用户可以保存多个时间表。以下是对 select/activate 特定保存的时间表采取的操作(屏幕截图的大小为 50% 并合并为一个图形):
- 屏幕截图 A:单击“更改活动”按钮调用 child 表单
- 屏幕截图 B:select 来自组合框的计划并单击激活 关闭 child 表单的选定计划,传递 selected 处理时间表。
- 屏幕截图 C – 使用 Close() 方法的结果: 计划定义屏幕填充了 selected 日程安排的详细信息,包括(如果需要)调用不同的 child 形成但 select 活动计划表实际上并未关闭 在 parent 表单开始处理填充数据之前;仅在通过单击“保存”或“取消”关闭 Child2 后,Child1 才会关闭。
- 屏幕截图 D – 使用 Hide() 方法的结果:按预期工作
相关代码(我认为)
public interface IselectSchedule
{
void SelectSchedule(string sName);
}
/// Parent form
public partial class DefineSched : Form, IDates, IDoWs, IselectSchedule
{
/// calling Child1
private void ChangeActvLBLasBTN_Click(Object sender, EventArgs e)
{
SetActvSchedule callSetActvSched = new SetActvSchedule(this);
callSetActvSched.StartPosition = FormStartPosition.Manual;
callSetActvSched.Location = new Point(this.Left + 45, this.Top + 25);
callSetActvSched.ShowDialog();
}
}
/// Child1 form
public partial class SetActvSchedule : Form
{
IselectSchedule _callingForm;
public SetActvSchedule(IselectSchedule caller)
{
InitializeComponent();
_callingForm = caller;
}
/// form content
private void SaveBTN_Click(Object sender, EventArgs e)
{
this.Close(); // not achieving my objective but Hide does
_callingForm.SelectSchedule(_sname);
}
}
/// back in Parent form
public void SelectSchedule(string sName)
{
_sName = sName;
bool useDB = false;
SetActvDisplay(useDB);
EditSaved(useDB);
}
private void EditSaved(bool useDB)
{
/// populate parent form data & call Child2
SelectDoW callSelectDoWs = new SelectDoW(this, det, det2);
callSelectDoWs.StartPosition = FormStartPosition.CenterParent;
callSelectDoWs.ShowDialog(owner: this);
/// ready for editing
我已经 researched/understand 决定隐藏还是关闭,我认为关闭在这里是合适的。我的问题是,既然 Close() 先于返回到 parent 表单,为什么在 parent 表单开始处理传递的信息之前该操作没有完成?
提前感谢您的任何见解。
虽然我相信我几乎可以使用上面建议的多线程方法,但我 运行 遇到了一个我无法解决的跨线程错误。经过进一步考虑,我可能一直在寻求一个不必要的复杂解决方案来实现一个非常简单的 objective;向用户提供一些选项并根据他们的选择采取行动。
简单的解决方案是在子表单中设置的父表单中的 public 静态字段,之后子表单完全关闭并控制 returns 到父表单:
/// Parent form
public partial class DefineSched : Form
{
public static string _sName;
/// calling Child
private void ChangeActvBTN_Click(Object sender, EventArgs e)
{
SetActvSchedule callSetActvSched = new SetActvSchedule();
callSetActvSched.ShowDialog();
ActvSchedOptions();
}
}
/// Child1 form
public partial class SetActvSchedule : Form
{
private void SaveBTN_Click(Object sender, EventArgs e)
{
DefineSched._sName = _sname;
this.Close();
}
}
/// back in Parent form
ActvSchedOptions()
{
/// series of conditional statements
这种方法避免了对接口的需要,并避免了 UI 线程过载。我怀疑它不会被认为是一个特别优雅的解决方案,但它有一个可取之处:它可以完美地完成手头的任务。