Winform异步加载数据弹窗等待效果

这篇博客介绍了如何使用C#实现异步加载数据的同时显示等待窗口,特别提到了.NET5之后BeginInvoke的弃用,并提供了两种不同的实现方法:一种是通过Action,另一种则是利用async/await。代码示例中展示了如何封装和调用这些方法,以实现带或不带返回值的异步操作。

首先自己添加一个窗体制作一个等待窗体

我的是gif动图,赖得写代码了

我是用Action方法做的,Func做法差不多就不介绍了

还有一种方法用async/await实现

值得一说的是在.net 5版本以后BeginInvoke不能用了,所以用async/await,这里我们来简单封装。如下:

        /// <summary>
        /// 异步加载数据并且弹出等待窗体
        /// </summary>
        /// <param name="action"></param>
        protected void LoadData(Action action)
        {
            if (action == null)
                return;
            using (FmLoading fl = new FmLoading())
            {
                LoadDataAsync(action, fl);


                fl.ShowDialog();
   
<think>首先,用户的问题是关于Winform应用程序的:如何关闭除主界面外的所有弹窗?用户意图是寻找一种方法来关闭除主窗体之外的所有其他窗体。 我需要基于系统级指令来构建我的回答: - 所有行内数学表达式使用$...$格式,但这个问题是关于Winform的,没有数学内容,所以我可能不需要使用数学表达式。 - 独立公式使用$$...$$格式,但同样,这里不适用。 - LaTeX语法正确:确保任何公式都正确。 - 使用中文回答:整个回答必须用中文。 - 生成相关问题:在回答结束后,生成相关问题。 - 回答中引用的段落末尾添加引用标识:如[^1]。用户提供了三个引用,我需要合理地引用它们。 用户提供的引用: - [^1]:关于Winform进度条弹窗和任务控制,使用CSkin界面库。 - [^2]:关于让弹窗不影响主界面,讨论关闭弹窗的顺序。 - [^3]:关于关闭登录界面的方法,使用MessageBox。 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 但在这个对话中,没有上一次的问题和回答,因为这是初始查询。用户还说:“我想用户意图是寻找在Winform应用程序中关闭除主界面外所有弹窗的方法。” 所以,我应该直接针对这个意图回答。 我的回答结构: 1. **理解用户意图**:确认用户想关闭所有其他窗体,只保留主界面。 2. **解决方案**:提供代码示例或方法来实现这个。 3. **代码示例**:使用C# Winform代码展示如何关闭除主窗体外的所有窗体。 4. **引用相关部分**:在适当的地方引用提供的引用。 5. **生成相关问题**:在回答结束时,列出相关问题。 核心方法: - 在Winform中,所有窗体都存储在Application.OpenForms集合中。 - 遍历这个集合,关闭所有不是主窗体窗体。 - 确保主窗体是已知的;通常,主窗体是启动窗体。 代码思路: ```csharp foreach (Form form in Application.OpenForms.Cast<Form>().ToList()) { if (form != mainForm) // mainForm是主窗体实例 { form.Close(); } } ``` - 需要小心处理,因为关闭窗体可能会引发事件。 - 使用.ToList()来避免修改集合时迭代错误。 引用用户提供的引用: - [^1]提到使用CSkin界面库,但用户问题不特定于CSkin,所以我应该保持通用。 - [^2]讨论关闭弹窗的顺序,可以引用来说明在关闭前处理逻辑。 - [^3]显示MessageBox,但这不是直接相关;用户想关闭弹窗,而不是显示。 我应该自然地融入引用: - 例如,在讨论弹窗管理时,引用[^2]关于关闭顺序。 - [^1]关于界面库,可能不直接相关,但可以提到如果使用自定义控件。 用户意图是关闭所有弹窗,包括对话框和子窗体。 回答结构: 1. **引言**:确认用户需求。 2. **方法**:解释如何实现。 3. **代码示例**:提供简单代码。 4. **注意事项**:讨论潜在问题。 5. **引用**:在相关点添加引用。 6. **相关问题**:生成几个相关问题。 用中文写。 最终回答: - 开头:直接回答。 - 中间:详细步骤。 - 结束:相关问题。</think>### Winform 如何关闭除主界面外的所有弹窗Winform 应用程序中,关闭除主界面外的所有弹窗是一个常见需求,通常用于清理界面或确保用户焦点集中在主窗体上。这可以通过遍历应用程序中所有打开的窗体(`Application.OpenForms` 集合),并关闭非主窗体的方式实现。以下是详细步骤和代码示例,确保方法安全可靠。 #### 解决方案步骤 1. **识别主窗体**:主窗体通常是应用程序启动时创建的窗体,您需要在代码中保存其引用(例如,在 `Program.cs` 中定义)。 2. **遍历并关闭非主窗体**:使用 `Application.OpenForms` 获取所有打开窗体,遍历时检查每个窗体是否为主窗体。如果不是,则调用 `Close()` 方法。 3. **处理潜在问题**: - 避免在遍历时修改集合:使用 `.ToList()` 创建副本,防止迭代错误。 - 考虑窗体关闭事件:某些弹窗可能有未保存数据或事件处理逻辑,建议在关闭前添加确认提示(如引用[^2]所述,先关闭弹窗再处理主逻辑)。 - 线程安全:如果涉及多线程,需在 UI 线程上操作(使用 `Invoke` 方法)。 #### 代码示例 以下是一个通用实现,基于 C# Winform。假设您的主窗体变量名为 `mainForm`(在 `Program.cs` 中初始化)。 ```csharp using System; using System.Linq; using System.Windows.Forms; // 在 Program.cs 中定义主窗体引用 static class Program { public static Form mainForm; // 保存主窗体实例 [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); mainForm = new MainForm(); // MainForm 是您的主窗体类 Application.Run(mainForm); } } // 在任意位置(如按钮点击事件)调用关闭弹窗的方法 private void CloseAllPopups() { // 遍历所有打开窗体,关闭非主窗体 foreach (Form form in Application.OpenForms.Cast<Form>().ToList()) { if (form != Program.mainForm) { form.Close(); // 关闭弹窗 } } } ``` #### 注意事项 - **引用集成**: - 如果您使用自定义界面库(如引用[^1]中的 CSkin),确保弹窗控件(如 `SkinProgressBar`)在关闭时释放资源,避免内存泄漏。引用[^1]提到通过继承窗体类实现圆角效果,但关闭逻辑与标准 Winform 相同。 - 引用[^2]建议在关闭弹窗前处理“正在加载”等状态:如果弹窗涉及任务执行,先关闭弹窗再继续主逻辑,或在必要时重新显示,以避免界面卡顿[^2]。 - 引用[^3]展示了使用 `MessageBox` 的示例,但 `MessageBox` 是模态对话框,需手动关闭;本方法适用于所有窗体类型,包括自定义弹窗。 - **潜在风险**: - 如果弹窗有未保存数据,强制关闭可能导致数据丢失。建议添加确认提示(例如,在 `form.Close()` 前检查 `form.DialogResult`)。 - 确保主窗体引用正确:如果主窗体未正确设置,可能导致误关闭。测试时使用调试模式验证。 - **性能优化**:此方法时间复杂度为 $O(n)$($n$ 为打开窗体数),在大多数场景下高效。但如果窗体过多,可考虑异步关闭。 通过此方法,您可以高效管理 Winform 界面,保持主界面清洁。如果问题复杂,建议结合具体场景调整。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值