热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#Winform进度条的使用

一个好的进度条能有效的改善用户体验。当然,前提是进度条做得好才行,做得差作用就正好相反了,可能造成程序假死、无法关闭等。下面是一个真实例子

一个好的进度条能有效的改善用户体验。当然,前提是进度条做得好才行,做得差作用就正好相反了,可能造成程序假死、无法关闭等。

下面是一个真实例子,我自己写代码的经验(由于我使用进度条都是自己琢磨,所以和网上的例子不太一样)。

以下是我一年前写的进度条,当时刚学C#,所以写出的进度条窗体效果非常差,正好做一个反例。

        public int current &#61; 0;//当前值public int max &#61; 100;//最大值public ProgressForm(){InitializeComponent();}//循环跑进度条public void pand(){int i, old &#61; 0;do{if (current !&#61; old){for (i &#61; 0; i < 10; i&#43;&#43;){this.progressBar1.Value &#43;&#61; 1;this.progressBar1.Update();Application.DoEvents();}old &#61; current;}this.progressBar1.Update();Application.DoEvents();if (current &#61;&#61; 0){this.label1.Text &#61; "正在写入论文信息&#xff0c;请稍等...";}else{this.label1.Text &#61; "正在写入论文正文&#xff0c;请稍等...";}}while (current !&#61; max);while (this.progressBar1.Value !&#61; this.progressBar1.Maximum){this.progressBar1.Value &#43;&#61; 1;this.progressBar1.Update();Application.DoEvents();}}//窗体显示时的事件private void ProgressForm_Shown(object sender, EventArgs e){this.progressBar1.Maximum &#61; max * 10;this.progressBar1.Value &#61; 0;pand();this.Close();}

好吧&#xff0c;代码非常繁琐&#xff0c;我稍微解释一下这段代码以及当时我的想法&#xff1a;

我定义了两个公共变量&#xff1a;max存后台需要完成任务任务数&#xff0c;current存当前完成了第几项任务。然后pand()方法负责循环检测current的值&#xff0c;然后给进度条增加值&#xff0c;当current等于max时停止循环关闭进度条窗体&#xff0c;代表任务完成。

                        while (this.progressBar1.Value !&#61; this.progressBar1.Maximum){this.progressBar1.Value &#43;&#61; 1;this.progressBar1.Update();Application.DoEvents();}

这段代码的作用是让进度条跑的时候不跳格&#xff0c;类似this.progressBar1.PerformStep();方法&#xff08;当时我并不知道进度条有这个方法&#xff09;。下面说一下这段代码存在的问题&#xff0c;首先使用无限循环会造成程序假死现象&#xff08;就是跑进度的时候无法关闭进度条窗体&#xff09;&#xff0c;这非常影响用户体验&#xff0c;其次是代码繁琐&#xff0c;明明是非常简单的事&#xff0c;写得那么繁琐&#xff0c;既影响阅读又影响性能&#xff0c;最后是进度条的画面和Value不同步&#xff08;即每次进度条的Value已经加完了&#xff0c;进度条还没跑完&#xff09;&#xff0c;导致用户看到的效果是进度还没跑完&#xff0c;进度条就关了。

下面看一下我修改后的进度条窗体代码&#xff1a;

        private int _current &#61; 0;/// 

/// 当前值/// public int Current{get { return _current; }set{_current &#61; value;AddValue();}}private int _max &#61; 100;/// /// 最大值/// public int Max{get { return _max; }set { _max &#61; value;this.progressBar1.Maximum &#61; (_max - 1) * 10;this.progressBar1.Value &#61; 0;}}MainForm father;public ProgressForm(MainForm main){father &#61; main;InitializeComponent();this.label1.Text &#61; "正在写入论文信息&#xff0c;请稍等...";}/// /// 给进度条加值的方法/// private void AddValue(){if (_current > 0){this.label1.Text &#61; "正在写入论文正文&#xff0c;请稍等...";}this.progressBar1.PerformStep();if (this._current * 10 > this.progressBar1.Maximum){this.DialogResult &#61; System.Windows.Forms.DialogResult.OK;this.Close();}}/// /// 取消按钮的方法/// private void Cancel(){father.CreateThesisIsRuning &#61; false;progressBar1.Style &#61; ProgressBarStyle.Marquee;label1.Text &#61; "取消中&#xff0c;请稍等...";while (true){if (!father.CreateThesisTh.IsAlive)break;Application.DoEvents();}}/// /// 取消按钮事件/// /// /// private void buttonX1_Click(object sender, EventArgs e){Cancel();}

同样是需要当前值和最大值变量&#xff0c;不同的是我把这两个字段封装起来了&#xff0c;AddValue()方法负责给进度条增加值&#xff0c;Cancel()方法负责执行用户点击取消按钮的操作。

在设置Current值时执行AddValue()方法&#xff0c;AddValue()方法中使用了this.progressBar1.PerformStep()&#xff0c;这个方法的作用是按照设置好的this.progressBar1.Step值给进度条增加值&#xff0c;比如Step&#61;10&#xff0c;调用这个方法就相当于给进度条添加10次值&#xff0c;每次增加1&#xff0c;就不会造成进度条跳跃格数过大&#xff0c;提升用户体验。

用户在点击取消按钮时&#xff0c;就设置后台进程CreateThesisIsRuning&#61;false&#xff0c;使进程停止&#xff0c;由于进程正常可能停止需要一定的时间&#xff0c;所以用一个循环去检测CreateThesisTh.IsAlive的值判断进程是否结束&#xff0c;此时还要修改进度条类型为ProgressBarStyle.Marquee&#xff0c;Application.DoEvents()可以避免循环卡死。

然后针对进度不同步&#xff0c;在设置Max值得时候&#xff0c;this.progressBar1.Maximum &#61; (_max - 1) * 10&#xff0c;将进度条的最大值设置成max最大值-10&#xff0c;然后最后判断进度条是否结束时使用this._current * 10 > this.progressBar1.Maximum去判断&#xff0c;这样就可以使进度条画面&#xff0c;原理是进度条画面更新比较慢&#xff0c;所以减小进度条的最大值&#xff0c;让进度条先跑完再执行完任务&#xff0c;造成进度条在等任务&#xff0c;虽然还是不同步&#xff0c;但是在用户体验上效果好多了。

下面看一下效果&#xff1a;

跑条中.png

图1 任务进行中

取消中.png

图2 任务取消中

以上是我自己想的一个进度条方案&#xff0c;如有雷同&#xff0c;纯属巧合&#xff0c;欢迎大家指正。


推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有