winform中一个窗口关闭后在主窗口上自动刷新显示的数据。谢谢
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了winform中一个窗口关闭后在主窗口上自动刷新显示的数据。谢谢相关的知识,希望对你有一定的参考价值。
在主窗体写:
form2 frm=new form2;
if (frm.ShowDialog() == DialogResult.OK)
//在form2关闭了,并且是OK的时候才执行
//然后在form2窗体的确定按钮事件里写,这样在点击form2的确定键后关闭form2提
//示主窗体你点击的是确定键,
this.DialogResult = DialogResult.OK;
this.Close();追问
谢谢你哈,能给我一个很简简单单的完成的例子吗?初学者
追答没写实例吖,自己多研究研究 便于记忆。 多看看书 C#入门经典 不错,网上很多电子书。
参考技术A 子窗口关闭的时候,传递状态给主窗口 参考技术B 用委托和事件 在子窗体里面顶一个委托和事件,很简单的 不清楚联系我追问还是不清楚哦。谢谢
在另一个线程上终止窗口
【中文标题】在另一个线程上终止窗口【英文标题】:Terminate Window on another thread 【发布时间】:2021-09-16 02:46:34 【问题描述】:我有一个简单的 C# winform 应用程序,我在其中生成了一个新线程来显示另一个 winform。一个过程完成后,我想使用下面的代码关闭该表单。我遇到的问题是,当我调用busyForm.BeginInvoke
时,它绕过了空检查并抛出错误。如何在另一个线程中正确关闭winform?
static Indicator busyForm;
public static async Task Execute()
Thread busyIndicatorthread = new Thread(new ThreadStart(()=>FormThread()));
busyIndicatorthread.SetApartmentState(ApartmentState.STA);
busyIndicatorthread.Start();
private static void FormThread()
busyForm = new Indicator();
busyForm.Closed += (sender2, e2) => busyForm.Dispatcher.InvokeShutdown();
Dispatcher.Run();
public static Task Execute()
Thread busyIndicatorthread = new Thread(new ThreadStart(()=>FormThread(hwind)));
busyIndicatorthread.SetApartmentState(ApartmentState.STA);
busyIndicatorthread.Start();
// dos some stuff
if (busyForm != null)
busyForm.BeginInvoke(new System.Action(() => busyForm.Close())); <--- throw null error
busyForm = null;
【问题讨论】:
拥有多个 UI 线程是非常不寻常的。你确定要走那条路吗?where I spawn a new thread to show another winform.
为什么?没有应用程序这样做,甚至不需要这样做。在所有应用程序中,忙碌和进度对话框都是由 UI 线程生成的。可能阻塞的操作在后台执行,例如在后台线程中或使用Task.Run
。 UI 使用事件或回调进行更新,例如使用 Progress< T>
类
【参考方案1】:
那是因为在调用.Close()
方法之前,时间已经过去,不能确定busyForm 是否存在。
事实上,有可能在new System.Action(() => busyForm.Close()
线程启动时,您的主线程转到busyForm = null;
。
您可以尝试将 null 移动到辅助线程。
if (busyForm != null)
busyForm.BeginInvoke(new System.Action(() =>
lock(busyForm)
busyForm.Close();
busyForm = null;
));
【讨论】:
你永远不应该对可能变为空的东西使用锁。锁定空对象会抛出ArgumentNullException
- 并不是真正的改进。【参考方案2】:
几乎没有应用程序启动另一个消息泵来显示通知。这不是必需的。在所有应用程序中,忙碌和进度对话框都是由 UI 线程生成和显示的。可能阻塞的操作在后台执行,例如在后台线程中或更好,使用async/await
和Task.Run。 UI 使用事件或回调进行更新,例如使用 Progress< T> 类。
不过,在这种情况下,似乎只需要在长时间运行的任务之前显示一个表单并在之后隐藏它:
public async void btnDoStuff_Async(object sender, EventArgs args)
//Disable controls, display indicator, etc
btnDoStuff.Enabled=false;
using var busyForm = new Indicator();
busyForm.Show();
try
var result=await Task.Run(()=> ActuallyDoStuffAndReturnResult());
//Back in the UI form
//Do something with the result
finally
//Close the busy indicator, re-enable buttons etc.
busyForm.Close();
btnDoStuff.Enabled=true;
finally
块可确保 UI 已启用,并且即使在出现错误时也会隐藏忙碌的表单。
20 多年前,一些 Visual Basic 6 应用程序确实启动了另一个 Window 消息泵来充当“服务器”。 Visual Basic 6 线程非常很古怪,所以人们使用各种技巧来解决它的限制。
【讨论】:
【参考方案3】:当你编写这段代码时:
busyForm.BeginInvoke(new System.Action(() => busyForm.Close())); <--- throw null error
busyForm = null;
它的执行顺序几乎可以肯定是这样的:
busyForm = null;
busyForm.Close();
难怪你得到一个空引用异常!
只需在调用中将表单设置为 null。这样就解决了。
然而,正确的做法是按照 Panagiotis Kanavos 的建议。
【讨论】:
以上是关于winform中一个窗口关闭后在主窗口上自动刷新显示的数据。谢谢的主要内容,如果未能解决你的问题,请参考以下文章
在winform中,关闭窗口时刷新父窗口(原来打开此窗口的窗口)
C# winform 关闭窗体后在打开 如何让打开的窗体还是原窗体 且打开的窗体还是原状态
C#winform中在一个主窗体中打开几个子集窗口,如何让子集窗口在主窗体中平均分布