C# WPF上位机开发(子窗口通知父窗口更新进度)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        这两天在编写代码的时候,正好遇到一个棘手的问题,解决之后感觉挺有意义的,所以先用blog记录一下,后面可以当成经验来参考。问题是这样的,本身软件在加载子窗口的时间可能会比较长,这么长的时间的加载,会给用户造成一个错觉,会以为这个软件是不是真的卡死了?所以在子窗口加载的过程中,我们希望子窗口根据不同的加载进度,更新父窗口中的进度条,至少让用户觉得软件还在跑,没有卡死。整个需求就是这么一个想法。

        为了解决这个问题,想了很多办法,最后还是通过BackgroundWorker和参数传递的方式才解决的。

1、首先设计主窗口界面

        主窗口界面不复杂,主要就两个控件。一个是按钮,用户弹出子窗口;一个是进度条,子窗口中的按钮按下去的时候,这个进度条就会慢慢更新到100%。

<Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Button  x:Name="Button1"  Content="Button1" Click="Button1_Click" HorizontalAlignment="Left" Margin="335,135,0,0" VerticalAlignment="Top" Width="75"/><ProgressBar Name="progressBar" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" Height="20" Margin="230,205,0,0"/></Grid>
</Window>

        整个显示效果是这样的,

2、主窗口的代码

        有了界面,下面开始设计主窗口的代码。整个代码其实有两块。一块是按钮Button1的回调函数,这部分就是弹出子窗口,还要给子窗口传递一个参数。另外一块就是注册BackgroundWorker变量以及它的回调函数。注意这个BackgroundWorker的变量是在构造函数里面进行设置的。而且刚刚谈到的子窗口传递参数,说的也就是这个BackgroundWorker变量。

        有兴趣的同学可以观察一下BackgroundWorker的回调函数ProgressChanged。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;namespace WpfApp
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{private BackgroundWorker worker;public MainWindow(){InitializeComponent();worker = new BackgroundWorker();worker.WorkerReportsProgress = true;worker.ProgressChanged += Worker_ProgressChanged;}private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e){progressBar.Value = e.ProgressPercentage;}private void Button1_Click(object sender, RoutedEventArgs e){ChildWindow childWindow = new ChildWindow(worker);childWindow.ShowDialog();}}
}

3、设计子窗口界面

        子窗口界面部分就比较简单了,就是一个按钮而已,

<Window x:Class="WpfApp.ChildWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp"mc:Ignorable="d"Title="ChildWindow" Height="450" Width="800"><Grid><Button x:Name="Button2" Content="Button2" Click="Button2_Click" HorizontalAlignment="Left" Margin="355,150,0,0" VerticalAlignment="Top" Width="75"/></Grid>
</Window>

        转成图形的话,它的界面是这样的,

4、子窗口代码设计

        有了子窗口,下面就要开始实现按钮的回调函数了。既然在主窗口中已经定义好了BackgroundWorker,那么回调函数需要做的就是有了进展之后,去ReportProgress就好了。这样有了这个ReportProgress就会进一步触发主窗口中的回调函数,这样主窗口中的进度条也会得到更新。并且所有操作都完毕之后,还会弹出一个MessageBox。大概就是这么一个过程。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
using System.ComponentModel;namespace WpfApp
{/// <summary>/// ChildWindow.xaml 的交互逻辑/// </summary>public partial class ChildWindow : Window{public int add_flag = 0;private BackgroundWorker worker;public ChildWindow(BackgroundWorker worker){InitializeComponent();this.worker = worker;}private void Button2_Click(object sender, RoutedEventArgs e){if (add_flag == 0){add_flag = 1;worker.DoWork += (s, args) =>{for (int i = 1; i <= 100; i++){worker.ReportProgress(i);Thread.Sleep(50);}};worker.RunWorkerCompleted += (s, args) =>{MessageBox.Show("Task finished!");};}worker.RunWorkerAsync();}}
}

        细心的同学应该还发现了,代码中还多了一个add_flag,这主要是为了防止在子窗口中重复按钮之后,反复进行进度条的更新。

5、编译和测试

        编译无误之后,就可以开始测试。测试的方式和之前说的一样,首先打开主窗口,利用按钮Button1再打开子窗口,进一步单击子窗口中的按钮Button2,如果发现主窗口的中的进度条可以正常更新,那说明一切流程都是ok的,否则就要去check一下问题,同时debug一下软件失败的原因。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/296959.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是docker和docker-compose?这些概念你必须知道

在后面的软件安装中&#xff0c;我们会使用到docker和docker-compose&#xff0c;为了帮助大家理解这两个工具&#xff0c;本文会先进行一个简单的介绍。 概括来说&#xff0c;Docker 和 Docker Compose 是两个可以让我们更方便地在Linux环境中搭建和运行应用的工具。这里我们以…

Pyramid:A Layered Sharding Blockchain System

在这篇文章中&#xff0c;提出 pyramid 技术&#xff0c;相比于完全分片&#xff0c;有些分片是存在 overlap 的。 将分片分成两类&#xff0c;i-shard 只负责进行片内交易的处理。 b-shard&#xff0c;包含多个i-shard的node&#xff0c;不仅进行片内交易&#xff0c;也负责处…

SpringCloudAlibaba Seata在Openfeign跨节点环境出现全局事务Xid失效原因底层探究

原创/朱季谦 曾经在SpringCloudAlibaba的Seata分布式事务搭建过程中&#xff0c;跨节点通过openfeign调用不同服务时&#xff0c;发现全局事务XID在当前节点也就是TM处&#xff0c;是正常能通过RootContext.getXID()获取到分布式全局事务XID的&#xff0c;但在下游节点就出现获…

20231222给NanoPC-T4(RK3399)开发板的适配Android11的挖掘机方案并跑通AP6398SV

20231222给NanoPC-T4(RK3399)开发板的适配Android11的挖掘机方案并跑通AP6398SV 2023/12/22 7:54 简略步骤&#xff1a;rootrootrootroot-X99-Turbo:~/3TB$ cat Android11.0.tar.bz2.a* > Android11.0.tar.bz2 rootrootrootroot-X99-Turbo:~/3TB$ tar jxvf Android11.0.tar.…

谷粒商城|仓储服务-仓库管理

配置服务中心 cloud:nacos:discovery:server-addr: 127.0.0.1:8848application:name: guliware在网关配置路由转发 guligateway .yml配置文件 - id: ware_routeuri: lb://guliwarepredicates:- Path/api/guliware/**filters:- RewritePath/api/(?<segment>.*),/$\{segm…

Java、SpringBoot中配置接口文档,knife4j、swagger

Java、SpringBoot中配置接口文档&#xff0c;knife4j、swagger knife配置 官网&#xff1a;https://doc.xiaominfo.com/ 我这里以最新版的为例&#xff0c;SpringBoot版本是3.0.0以上的 需要注意的是自动集成了swagger&#xff0c;每个SpringBoot版本会对应其knfie版本&…

Java实现非对称加密【详解】

Java实现非对称加密 1. 简介2. 非对称加密算法--DH&#xff08;密钥交换&#xff09;3. 非对称加密算法--RSA非对称加密算法--EIGamal5. 总结6 案例6.1 案例16.2 案例26.3 案例3 1. 简介 公开密钥密码学&#xff08;英语&#xff1a;Public-key cryptography&#xff09;也称非…

实习知识整理6:前后端利用ajax数据传输的四种方式

方式1&#xff1a;前端发送key/value(String字符串)&#xff0c;后台返回文本 前端&#xff1a; <input id"test1" type"button" value"前端发送key/value(String字符串)&#xff0c;后台返回文本"/> $(function() {$("#test1&quo…

R语言 | 组学各类图形绘制资源

一边学习&#xff0c;一边总结&#xff0c;一边分享&#xff01; 写在前面 今天分享在GitHub中找到的教程资源&#xff0c;此教程是来自iMeta期刊及“农心生信工作室”的作品。发表在GitHub中&#xff0c;大家可以自行下载。 包含了21个图形的绘制&#xff0c;我大体看了一下…

超全面!8 种互联网常用生命周期完整指南~

什么是生命周期&#xff1f; 百度给出的定义是&#xff1a;生命周期就是指一个对象的生老病死。 生命周期的概念应用很广泛&#xff0c;特别是在政治、经济、环境、技术、社会等诸多领域经常出现&#xff0c;其基本涵义可以通俗地理解为“从摇篮到坟墓”的整个过程。对于某个…

百度网盘win11端扫一扫登录二维码无法显示问题的解决方法

百度网盘win11端扫一扫登录二维码无法显示问题的解决方法 文章目录 问题描述解决方法1、打开Edge 设置2、进入Reset settings页面3、单击重置按钮&#xff1a;4、重新打开百度网盘APP 问题描述 今天在win11端扫描登录百度云网盘时&#xff0c;二维码无法加载出来&#xff0c;具…

第十三章 常用类(包装类和 String 相关类)

一、包装类 1. 包装类的分类 &#xff08;1&#xff09;针对八种基本数据类型相应的引用类型—包装类 &#xff08;2&#xff09;有了类的特点&#xff0c;就可以调用类中的方法。 2. 包装类和基本数据类型的转换 &#xff08;1&#xff09;jdk5 前的手动装箱和拆箱方式 publ…