[C#] (原创)进度等待窗口(附:自定义控件的使用)

1、前言

技术没有先进与落后,只有合适与不合适。html

在程序当中,常常有耗时较长的操做,为了给用户更好的体验,就须要给用户一个及时的反馈,这种时候就须要用到进度等待窗口。安全

实现进度等待窗口的技术有不少,好比:BackgroundWorker、Thread等。函数

不过技术不是难点,难点在于怎么使等待窗口美观实用。因此本文中就基于前几篇的自定义控件:LProgressBar和LLabel,去实现进度等窗口。工具

相关文章:布局

[C#] (原创)一步一步教你自定义控件——04,ProgressBar(进度条)性能

[C#] (原创)一步一步教你自定义控件——05,Label(原生控件)  动画

 

相信看完的你,必定会有所收获。线程

本文地址:https://www.cnblogs.com/lesliexin/p/14121618.html3d


 

2、前期分析

(一)为何须要进度等窗口?

为了在执行耗时操做时,给用户更好的、更直观的体验。orm

(二)预期功能效果

1,功能

(1),支持“取消”操做,固然也支持“不能取消”操做。

(2),支持进度明确与进度不明确时显示不一样样式。

(3),支持明细进度。

2,效果

Win7:

Win10:

 


 

3、开始实现

(一)布局窗体

 1,新建窗体

(1),在工程上右击,选择“添加”->“窗体(Windows 窗体)”,命名为:LProgress.cs。

 

(2),修改窗体相关属性

Font:微软雅黑,9pt。比之默认的“宋体,9pt”的效果更加美观。

BackColor:White。更加美观,特别是在Win10上。

ForeColor:Black。为了防止被某些系统主题影响而显示的不是黑色。

FormBorderStyle:FixedDialog。使用户不可调用窗口尺寸。

MaximizeBox:False。不显示最大化按钮。

MinimizeBox:False。不显示最小化按钮。

ShowIcon:False。不显示窗口图标。

ShowInTaskbar:False。不在任务栏上显示图标。

TopMost:True。置顶显示窗口。

 

2,添加控件

这里须要说明一下,在添加控件时,若是如本文这样窗体与自定义控件工程在同一个解决方案中,那么在工具栏的最上方会自动显示当前工具中的自定义控件,选中便可使用。

若是是窗体与自定义控件工程不在同一个解决方案中,好比引用的是自定义控件的DLL文件,那么就须要将自定义控件DLL拖到工具栏上,此时工具栏上就会显示出里面的自定义控件。

 

(1)整体控件布局

(2)lPBar_Main(主进度)

控件:LProgressBar

关键属性:

 

(3)lPBar_Child(子进度)

控件:LProgressBar

关键属性:

 

 

(4)lbl_Main(主进度文本)

控件:LLabel

关键属性:

 

 

(5)lbl_Child(子进度文本)

控件:LLabel

关键属性:

 

 

(6)btn_Cancel(取消按钮)

控件:Button

关键属性:

 

 

(7)相关说明

 这里说下lbl_Main和lbl_Child为何不使用原生Label控件,而使用自定义LLabel控件。

由于在实际运行时,窗口大小是固定不变的,因此若是内容过多时,若是使用原生Label,就会在鼠标移上去后显示悬浮提示,对总体外观有所影响。若是内容变化快的话,悬浮提示也会频繁显示,但提示的文本却早已过去,没有提示的意义。

因此此处使用了基于原生控件改造的自定义控件:LLabel。(详见:[C#] (原创)一步一步教你自定义控件——05,Label(原生控件)  )

这样经过属性”L_EnableAutoTip=False“,就能够再也不显示悬浮提示。

 

 (二)添加属性

1,是否显示“取消”按钮

对于耗时操做,有的时候是可让用户取消的;而有的时候,则是不能让用户取消。因此须要一个属性去控制是否显示“取消”按钮。

同时,为了美观,在不显示“取消”按钮时,调整窗口高度到合适位置。

 

2,主进度条模式(进度已知/进度未知)

一些操做的进度是已知的,好比下载进度、复制进度;而有一些操做的的进度是未知的,好比查询操做、调用其余耗时任务等。

针对进度已知仍是进度未知,则进度条的样式也须要有相应的改变。

 

 

3,窗口标题

当前进度等待窗口的标题

 

 

4,默认显示的主进度文本

默认的主进度文本

 

 

5,是否显示子进度条

由于大部分时候只须要一个进度,因此子进度条默认是不显示的。并且,子进度条的做用决定了子进度条自己是能够灵活显示/不显示的。

本属性只是提供一个初始化的状态。

 

 

6,自定义参数

由于进度等待窗口是一个单独的窗体,而耗时操做也是在本窗口中执行,因此就须要进行数据的交互,而此参数便是为了进行数据的交互。

 

 

(三)添加构造函数

为了方便调用,为窗口增长一带参数的构造函数。

这里给你们一个小技巧,在添加构造函数时,能够借用VS的“快速操做和重构...”功能来快速生成构造函数。

 

(四)添加事件

 本篇中执行耗时操做所采用的方法是开一新线程去执行,此方法很是简单且使用方便,因此须要添加一个事件,以让调用者在事件中执行耗时任务。

 

(五)添加公共方法

由于采用的是线程+事件,因此须要开放一些公共方法,以供调用者在事件实现中使用。

1,更新主进度文本

此方法用于更新主进度文本的内容。

 

(1),在方法中判断本次更新文本是否与当前显示文本是否一致:if(sMsg!=sLastMainMsg,是为了减小没必要要的赋值,减小闪烁,提升性能。(下同将再也不赘述)

(2),由于是在新线程中操做控件,因此若是直接操做控件的话,好比给控件赋值,将会提示“线程间操做无效。从不是建立控件'XXX'的线程访问它”的错误,这种状况下须要经过委托的方式去去操做控件。(固然也可使用不安全代码去解除这种限制,但不推荐使用。)(下同将再也不赘述)

 

2,更新主进度条进度值

此方法用于在主进度条是进度已知时,更新主进度条的进度。

 

3,更新子进度文本

此方法用于更新子进度文本。

4,更新子进度条进度值

此方法用于在子进度条是进度已知时,更新子进度条的进度。

 

5,改变子进度条显示状态

由于子进度条是灵活显示的,因此提供本方法去改变进度条的显示状态。

 

6,改变子进度条样式(进度已知/进度未知)

由于子进度条是灵活显示的,因此提供本方法去改变进度条的样式,是进度已知时样式仍是进度未知时样式。

当是进度未知时,要自动启动进度条动画。

 

7,退出

在事件中实现操做时,可使用本方法手动结束等待窗口。

 

(六)事件实现

1,窗口加载事件

在窗口加载时,咱们要知足如下条件:

(1),为了更加美观,因此咱们不会隐藏掉“关闭”按钮,可是“关闭”按钮会和“取消”按钮功能相冲突,特别是在不能取消时。

因此咱们要将“关闭”按钮无效化。主要使用到了系统API:GetSystemMenu和RemoveMenu

(2),若是是进度未知时,要令主进度条开始动画。

(3),开启新线程。此线程便是用来执行耗时任务的,因此要在此线程方法中触发事件委托,以供调用者实现。

 

因此,加载的实现以下:

2,“取消”按钮事件

点击“取消”时,要知足如下几个条件:

(1),若是主进度条是进度未知,则中止进度条动画。

(2),安全退出。

 

因此,“取消”按钮的实现以下:


 

4、效果演示

(1),新建窗体,添加LSwitchButton、Button、Label,以下:

 

(2),在“进度窗口”点击事件中调用进度等待窗口。

 

(3),实现耗时任务

(4),运行

 


 

 

5、结束语

本篇所实现的进度等待窗口,技术上很简单,但在美观上、功能上并不弱,并且使用起来也简单。做为平常使用也是足够的。

本篇文章的目的更多的是为了给你们一个使用自定义控件的例子,毕竟自定义控件要在实际的应用中才能体现出价值。

不要被常规思惟所束缚,相信本身所掌握的知识。

 


 

6、源代码及工程下载

https://files.cnblogs.com/files/lesliexin/05,LProgress.7z

相关文章
相关标签/搜索