ExtJs4 笔记(8) Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件
25-02-27
13
在这篇文章中,我们将为您详细介绍ExtJs4笔记的内容,并且讨论关于8Ext.slider滚轴控件、Ext.ProgressBar进度条控件、Ext.Editor编辑控件的相关问题。此外,我们还会涉及
在这篇文章中,我们将为您详细介绍ExtJs4 笔记 的内容,并且讨论关于8 Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件 的相关问题。此外,我们还会涉及一些关于android ListView和ProgressBar(进度条控件)的使用方法、Android ProgressBar:进度条控件、Android进度条控件progressbar使用方法详解、C# 根据BackgroundWoker异步模型和ProgressBar控件,自定义进度条控件 的知识,以帮助您更全面地了解这个主题。
本文目录一览:
ExtJs4 笔记(8) Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件 本篇要登场的有三个控件,分别是滚轴控件、进度条控件和编辑控件。
一、滚轴控件 Ext.slider
1.滚轴控件的定义
下面我们定义三个具有代表意义滚轴控件,分别展示滚轴横向、纵向,以及单值、多值选择的特性:
[html]
<h1>滚轴控件</h1>
<div>
<h2>横向,初始值50</h2>
<div id="slider1"></div>
<h2>纵向,带提示</h2>
<div id="slider2"></div>
<h2>多值,自定义提示</h2>
<div id="slider3"></div>
</div>
[Js]
//横向,初始值50
var slider1 = Ext.create('Ext.slider.Single',{
renderTo: 'slider1',width: 214,minValue: 0,maxValue: 100,value: 50
});
//纵向,带提示
new Ext.create('Ext.slider.Single',{
renderTo: 'slider2',height: 150,maxValue: 20,vertical: true,plugins: new Ext.slider.Tip()
});
//多值,自定义提示
var slider3 = Ext.create('Ext.slider.Multi',{
renderTo: 'slider3',values: [5,12],plugins: new Ext.slider.Tip({
getText: function (thumb) {
return Ext.String.format('当前:<b>{0}/20</b>',thumb.value);
}
})
});
2.获取、设置滚轴控件的值 [html]
<h1>操作滚轴控件</h1>
<div>
<button id="button1">设置滚轴1的值为10</button>
<button id="button2">获取滚轴1的值</button>
<button id="button3">设置滚轴3的值为10,15</button>
<button id="button4">获取滚轴3的值集合</button>
</div>
[Js]
//设置滚轴1的值为10
Ext.fly("button1").on('click',function () {
slider1.setValue(10);
});
//获取滚轴1的值
Ext.fly("button2").on('click',function () {
Ext.MessageBox.alert("获取值","滚轴1的值:" + slider1.getValue());
});
//设置滚轴3的值为10,15
Ext.fly("button3").on('click',function () {
slider3.setValue(0,10);
slider3.setValue(1,15);
});
//获取滚轴3的值集合
Ext.fly("button4").on('click',"滚轴3的值集合:" + slider3.getValues());
});
3.效果展示
二、进度条控件 Ext.ProgressBar
1.加载进度条 [html]
<div>
<button id="button1">执行</button>
<div id="p1"></div>
</div><br />
[Js]
//加载进度条
var progressBar1 = Ext.create("Ext.ProgressBar",{
id: "progressBar1",text: '准备中...',renderTo: 'p1'
});
Ext.fly("button1").on('click',function () {
//模拟加载环境
var f = function (v) {
return function () {
var i = v / 12;
progressBar1.updateProgress(i,'进度:' + v + '/12');
if (v == 12) {
Ext.Msg.alert("提示","加载完毕!");
progressBar1.reset(); //复位进度条
progressBar1.updateText("完成。");
}
};
};
for (var i = 1; i < 13; i++) {
setTimeout(f(i),i * 200);
}
});
2.等候进度条 [html]
<div>
<button id="button2">执行</button>
<div id="p2"></div>
<span id="p2text"></span>
</div><br />
[Js]
//等候进度条
var pbar2 = Ext.create("Ext.ProgressBar",{
id: "progressBar2",renderTo: 'p2',width: '150px'
});
pbar2.on('update',function (val) {
//每次更新可以执行的动作
Ext.fly('p2text').dom.innerHTML += '>';
});
Ext.fly("button2").on('click',function () {
Ext.fly('p2text').update('正在启动windows2000:');
pbar2.wait({
interval: 200,//每次更新的间隔周期
duration: 5000,//进度条运作时间的长度,单位是毫秒
increment: 5,//进度条每次更新的幅度大小,表示走完一轮要几次(默认为10)。
fn: function () { //当进度条完成自动更新后执行的回调函数。该函数没有参数。
Ext.fly('p2text').update('完成。');
}
});
});
3.等候进度条,等待第三方事件 [html]
<div>
<button id="button3">执行</button>
<div id="p3"></div>
<span id="p3text"></span>
</div>
[Js]
//等候进度条,当第三方事件结束时,停止。
var pbar3 = Ext.create("Ext.ProgressBar",{
renderTo: 'p3',width: '250px'
});
Ext.fly("button3").on('click',function () {
pbar3.wait({
interval: 100,increment: 5
});
Ext.fly('p3text').update('第三方事件正在执行,请稍候....');
setTimeout(function () {
pbar3.reset();
Ext.fly('p3text').update('执行完毕.');
},5000);
});
4.效果展示
三、编辑控件 Ext.Editor
编辑控件可以作用在一般html元素或者其他ext基本控件上,从而然这些基本元素和控件具备了编辑某些值的能力。
1.用文本框编辑普通文本
下面通过一个编辑控件作用在span标签上,双击该标签即可编辑该标签的文本类容。
[html]
<h1>用文本框编辑普通文本</h1>
<div>
<span id="span1">请双击我修改文字</span>
</div>
[Js]
//用文本框编辑普通文本
var editor1 = new Ext.Editor({
shadow: false,completeOnEnter: true,//按回车时自动完成
cancelOnesc: true,//按ESC自动退出编辑
updateEl: true,//有变化时更新
ignoreNoChange: true,//不理会没有变化的情况
listeners: {
complete: function (editor,value,oldValue) {
Ext.Msg.alert('文本被改变',"从“" + oldValue + "” 变为“" + value + "”");
}
},field: {
allowBlank: false,xtype: 'textfield',width: 150,selectOnFocus: true
}
});
Ext.get("span1").on('dblclick',function (event,span1_dom) {
editor1.startEdit(span1_dom);
});
效果如下:
处于编辑状态时:
2.用下拉列表编辑
这个例子要修改Ext.Panel控件的标题。
[html]
<h1>用下拉列表编辑</h1>
<divid="div2">
</div>
[Js]
//用下拉列表编辑
var editor2 = new Ext.Editor({
shadow: false,cancelOnesc: true,updateEl: true,ignoreNoChange: true,listeners: {
complete: function (editor,field: {
width: 110,id: "combo1",//renderTo: 'div2',triggerAction: 'all',xtype: 'combo',editable: false,forceSelection: true,store: ['下拉项1','下拉项2','下拉项3']
}
});
var panel = new Ext.Panel({
renderTo: "div2",width: 200,height: 50,collapsible: true,layout: 'fit',title: '请双击标题',listeners: {
afterrender: function (panel) {
panel.header.titleCmp.textEl.on('dblclick',label1_dom) {
editor2.startEdit(label1_dom);
});
}
}
});
效果如下:
处于编辑状态时:
出处:[Lipan] (http://www.cnblogs.com/lipan/)
android ListView和ProgressBar(进度条控件)的使用方法 ListView控件的使用: ListView控件里面装的是一行一行的数据,一行中可能有多列,选中一行,则该行的几列都被选中,同时可以触发一个事件,这种控件在平时还是用得很多的。 使用ListView时主要是要设置一个适配器,适配器主要是用来放置一些数据。使用起来稍微有些复杂,这里用的是android自带的SimpleAdapter,形式如下: android.widget.SimpleAdapter.SimpleAdapter(Context context,List<? extends Map<String,?>> data,int resource,String[] from,int[] to) 由此可以看出函数的第2个参数为一个list,该list里面存放的是一些hashmap,hashmap是一些映射,里面放的是键值对;第3个参数为1个布局文件,即适配器输出的布局;第4个参数为字符数组,数组的内容为参数list中map每列的列名;第5个参数为整型数组,其意思为第4个参数对应显示的值的格式,一般为控件。 因为第3个参数为1个布局文件,所以我们该工程中我们需要再单独添加一个xml文件。 同时我们要知道设置ListView的监听器是用onListItemClick()函数。 另外还需注意的是在java中定义数组类型并初始化时中间不需要等号,例如 new String[]{"user_name","user_birthday"}。 这次实验的参考的是mars老师的资料. ListView使用的显示效果如下:
每次选中一行时在后台会相应的输出该行的位置和id,依次选中这三行.
后台输出为:
实验代码如下:
MainActivity.java:
package com.example.control3;
import java.util.ArrayList; import java.util.HashMap;
import android.app.ListActivity; import android.os.Bundle; import android.view.View; import android.widget.ListView; import android.widget.SimpleAdapter;
public class MainActivity extends ListActivity {
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //建立一个ArrayList,ArrayList里面放的是Hash表 ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>(); HashMap<String,String>map1 = new HashMap<String,String>(); HashMap<String,String>map2 = new HashMap<String,String>map3 = new HashMap<String,String>(); //给Hash表中填入键值对 map1.put("user_name","小红"); map1.put("user_birthday","2012_07_30"); map2.put("user_name","小明"); map2.put("user_birthday","2012_07_31"); map3.put("user_name","小冬"); map3.put("user_birthday","2012_08_01"); list.add(map1); list.add(map2); list.add(map3); //在该activity中创建一个简单的适配器 SimpleAdapter listadapter = new SimpleAdapter(this,list, R.layout.activity_user,new String[]{ "user_name","user_birthday"},new int[] {R.id.user_name,R.id.user_birthday}); //载入简单适配器 setlistadapter(listadapter); }
//ListView监听器响应函数 @Override protected void onListItemClick(ListView l,View v,int position,long id) { // Todo Auto-generated method stub super.onListItemClick(l,v,position,id); System.out.println("id--------------------" +id); System.out.println("Position-------------" + position); } }
activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/listLinearLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ListView android:id="@id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" android:drawSelectorOnTop="false" android:scrollbars="vertical" /> </LinearLayout> </LinearLayout> activity_user.xml: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" android:padding="10dip" > <!-- 该布局文件时水平方向上2个TextView控件,并设置了其相应的属性 --> <TextView android:id="@+id/user_name" android:layout_width="180dip" android:layout_height="30dip" android:textSize="10pt" android:singleLine="true" /> <TextView android:id="@+id/user_birthday" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textSize="10pt" android:gravity="right" /> </LinearLayout> ProgressBar控件的使用 :
ProgressBar控件的使用比较简单,在android开发中,其默认的形式是1个圆周型的进度条,也就是代表一直在等待,这时候是看不到实际上完成的进度的。所以在程序中我们可以设置进度条的形状,比如呈水平或者垂直。界面中有1个按钮,一开始时是看不到进度条的,当按下按钮时,会弹出2个进度条,1个呈水平状,一个还是圆形。且这2个进度条出现在按钮的上面,为什么会这样呢?因为这个activity布局中,采用的是线性布局,而那2个进度条是放在button的前面,只是一开始没有设置显示出来而已。继续按进度条时,进度条会前进。且这里进度条显示分为主进度条显示和次进度条显示。
实验的结果如下:
MainActivity.java:
package com.example.control2;
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar;
public class MainActivity extends Activity {
private int i = 0; private ProgressBar bar1 = null; private ProgressBar bar2 = null; private Button button = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bar1 = (ProgressBar)findViewById(R.id.bar1); bar2 = (ProgressBar)findViewById(R.id.bar2); button = (Button)findViewById(R.id.btn); button.setonClickListener(new MyButtonOnClickListener()); } class MyButtonOnClickListener implements OnClickListener{
public void onClick(View v) { if( 0 == i ) { bar1.setVisibility(View.VISIBLE); bar2.setVisibility(View.VISIBLE); } else if( i < bar1.getMax() ) { //设置主进度和次进度 bar1.setProgress(i); bar1.setSecondaryProgress(i+10); } i+=10; }
} }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/china" /> <ProgressBar android:id="@+id/bar1" android:layout_width="fill_parent" android:layout_height="50dip" android:visibility="gone" /> <ProgressBar android:id="@+id/bar2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" /> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button" /> </LinearLayout>
总结: 通过这次实验,对ListView和ProgressBar这2个进度条的使用有了个初步的了解,其中ListView进度条的使用需要用的到适配器,而视频器的构造稍微有点复杂,需要对各个参数彻底的了解。 作者:tornadomeet
Android ProgressBar:进度条控件 当应用程序在后台运行时,可以使用进度条(ProgressBar)反馈给用户当前的进度信息。进度条被用以显示当前应用程序的运行状况、功能完成多少等情况。 Android SDK 提供两种样式的进度条,一种是圆形的进度条,另一种是水平进度条。其中圆形进度条分大、中、小三种。
进度条本质上是一个整数,显示当前的整数值在特定范围内的比重。下面用一个简单的实例讲解 ProgressBar 组件的使用方法。
在工程 WidgetDemo 的布局文件 main.xml 中添加一个名为 ProgressBarDemo 的 Button,用以启动 ProcessBaractivity。
在 main.xml 中添加代码如下:
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ProgressBarDemo"/>
单击 Button 并启动 ProcessBaractivity 的代码如下:
Button processbtn = (Button)this.findViewById(R.id.button7);
processbtn.setonClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent;
intent = new Intent(MainActivity.this, ProcessBaractivity.class);
startActivity(intent);
}
});
同时在 AndroidManifest.xml 文件中声明该 Activity:
<activity android:name=".ProcessBaractivity"></activity>
ProcessBaractivity 的运行效果如图 1 所示。
图 1 ProcessBaractivity 的运行效果
ProcessBaractivity 使用的布局文件为 processbar.xml,其内容如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/progressBar2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/progressBar3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/progressBar4"
android:layout_width="209dp"
android:layout_height="30dp"
android:max="100" />
</LinearLayout>
该布局中放置了小、中、大三种类型的圆形进度条各一个,以及一个水平放置的条形进度条。
一般情况下,开发人员不会为圆形进度条指定进度,圆形进度条只是展示运行效果,而不反映实际的进度。条形进度条则不同,开发人员会为条形进度条指定最大值,以及进度条当前值的获取方法。
在本实例中,条形进度条的最大值为100。
ProcessBaractivity.java 的代码如下:
package introduction.android.widgetdemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;
public class ProcessBaractivity extends Activity {
ProgressBar progressBar;
int i = 0;
int progressBarMax = 0;
/* 创建Handler对象*/
Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.processbar);
progressBar = (ProgressBar) findViewById(R.id.progressBar4);
/* 获取最大值*/
progressBarMax = progressBar.getMax();
/* 匿名内部类启动实现效果的线程*/
new Thread(new Runnable() {
@Override
public void run() {
while (i++ < progressBarMax) {
//设置滚动条当前状态值
progressBar.setProgress(i);
try {
Thread.sleep(15);
} catch (Exception e) {
e.printstacktrace();
}
}
}
}).start();
}
}
ProcessBaractivity 对水平进度条进行了处理。先获取了水平进度条的最大值,然后启动了一个线程,由该线程来控制进度条的值,从 0 开始,每隔 15 毫秒增加 1。
Android进度条控件progressbar使用方法详解 一、简介
二、方法
1)进度条ProgressBar使用方法
1、在layout布局文件中创建ProgressBar控件
<ProgressBarandroid:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="30"
/>
2、用ProgressBar对象指向ProgressBar控件
private ProgressBar pb_progressBar1;
pb_progressBar1=(ProgressBar) findViewById(R.id.pb_progressBar1);
3、通过ProgressBar对象的getProgress()和setProgress()方法对进度进行修改
if(progress<=100){
progress=pb_progressBar1.getProgress();
progress+=(int)(100*0.2);
pb_progressBar1.setProgress(progress);
}else progress=100;
三、代码实例
效果图:
点击增加进度按钮:
点击减少进度按钮:
代码:
fry.Activity01
package fry;
import com.example.Ex26ProgressBar.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
public class Activity01 extends Activity implements OnClickListener{
/*
* 进度条ProgressBar使用方法
* 1、在layout布局文件中创建ProgressBar控件
* 2、用ProgressBar对象指向ProgressBar控件
* 3、通过ProgressBar对象的getProgress()和setProgress()方法对进度进行修改
*
*/
private Button btn_addProgress;
private Button btn_minusProgress;
private ProgressBar pb_progressBar1;
private int progress;
@Override
protected void onCreate(Bundle savedInstanceState) {
// Todo Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity01);
btn_addProgress=(Button) findViewById(R.id.btn_addProgress);
btn_minusProgress=(Button) findViewById(R.id.btn_minusProgress);
pb_progressBar1=(ProgressBar) findViewById(R.id.pb_progressBar1);
btn_addProgress.setonClickListener(this);
btn_minusProgress.setonClickListener(this);
}
@Override
public void onClick(View v) {
// Todo Auto-generated method stub
switch (v.getId()) {
case R.id.btn_addProgress:
if(progress<=100){
progress=pb_progressBar1.getProgress();
progress+=(int)(100*0.2);
pb_progressBar1.setProgress(progress);
}else progress=100;
break;
case R.id.btn_minusProgress:
if(progress>=0){
progress=pb_progressBar1.getProgress();
progress-=(int)(100*0.2);
pb_progressBar1.setProgress(progress);
}else progress=0;
break;
default:
break;
}
}
}
/Ex26ProgressBar/res/layout/activity01.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- style设置控件样式 -->
<!-- 用?来引用东西 -->
<ProgressBarandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ProgressBarandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ProgressBarandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ProgressBarandroid:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="30"
/>
<ProgressBar
android:id="@+id/pb_progressBar1"android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="50"
android:secondaryProgress="80"
android:layout_marginTop="30dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/btn_addProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="增加进度"
android:layout_weight="1"
/>
<Button
android:id="@+id/btn_minusProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="减少进度"
android:layout_weight="1"
/>
</LinearLayout>
</LinearLayout>
四、注意点
1、通过ProgressBar对象的getProgress()和setProgress()方法对进度进行修改
progress=pb_progressBar1.getProgress();
progress+=(int)(100*0.2);
pb_progressBar1.setProgress(progress);
2、遇到不知道的控件和属性,可以通过set和get方法来看看怎么使用
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
C# 根据BackgroundWoker异步模型和ProgressBar控件,自定义进度条控件
前言
程序开发过程中,难免会有的业务逻辑,或者算法之类产生让人能够感知的耗时操作,例如循环中对复杂逻辑处理;获取数据库百万乃至千万级数据;http请求的时候等...... 用户在使用UI操作并不知道程序的内部处理,从而误操作导致程序无响应,关闭程序等待影响体验的情况,因此,在等待过程中提供友好的等待提示是有必要的,接下来 我们一起封装一个自定义进度条控件!
主要使用技术(C#相关)
BackgroundWoker
异步模型
ProgressBar
控件
泛型
定时器 System.Timers.Timer
自定义控件开发
项目解决方案
BackgroundworkerEx : 自定义进度条控件工程
Test : 调用BackgroundworkerEx的工程(只是展示如何调用)
处理控件样式
新建一个ProgressbarEx名称的 用户控件
添加Labal控件(lblTips),用于展示进度条显示的信息状态
添加一个PictureBox控件(PicStop),充当关闭按钮,用于获取用户点击事件,触发关闭/终止进度条
添加进度条ProgressBar控件(MainProgressBar)
处理代码如下:
进度条样式为"不断循环",并且速度为50
该自定义用户控件不展示在任务栏中
图片控件被点击事件------>设置当前属性IsStop=true
,指示过程终止;
TipMessage
属性,用于设置进度条的信息
SetProgressValue(int value)
设置进度条的Value
属性,使得在ProgressBarStyle.Marquee
样式中动画平滑
MouseDown
/MouseUp
/MouseMove
这三个事件是用于拖动无边框的用户控件(代码就不贴了 )
public ProgressbarEx()
{
InitializeComponent();
MainProgressBar.Style = ProgressBarStyle.Marquee;
MainProgressBar.MarqueeAnimationSpeed = 50;
this.ShowInTaskbar = false;
PicStop.Click += (s, eve) =>
{
IsStop = true;
};
this.MouseDown += CusProgressForm_MouseDown;
this.MouseUp += CusProgressForm_MouseUp;
this.MouseMove += CusProgressForm_MouseMove;
}
/// <summary>
/// Need Stop ?
/// </summary>
public bool IsStop { get; private set; } = false;
/// <summary>
/// TipMessage
/// </summary>
public string TipMessage { get; set; }
/// <summary>
/// TipMessage
/// </summary>
public string TipMessage
{
get
{
return lblTips.Text;
}
set
{
lblTips.Text = value;
}
}
/// <summary>
/// Set ProgressBar value ,which makes ProgressBar smooth
/// </summary>
/// <param name="value"></param>
public void SetProgressValue(int value)
{
if (MainProgressBar.Value == 100) MainProgressBar.Value = 0;
MainProgressBar.Value += value;
}
到现在,这个自定义进度条控件的样式基本完成了.
功能逻辑处理
运行前所需
定义BackgroundWorkerEx<T>
泛型类,并且继承于 IDisposable
释放资源;
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
try
{
DoWork = null;
RunWorkCompleted = null;
WorkStoped = null;
_mWorkerThread = null;
_mWorker.Dispose();
_mWorker = null;
_mTimer = null;
}
catch (Exception){}
}
T
用与异步处理的时候,传递T
类型
因为我们是通过.Net 的 BackgroundWorker
异步模型来做的,所以我们理所当然定义相关的事件:
异步开始
异步完成
加上我们自定义扩展的异步停止
......报告进度事件在此进度条样式中并不需要
我们先定义这四个事件所用到的参数,因为在BackgroundWorkerEx<T>
泛型类中,我们还是使用BackgroundWorker
来处理异步过程,因此我们定义的参数泛型类需要继承原来的参数类型,并且在传输传递中,将原生BackgroundWorker
的Argument
,Result
属性转成全局的泛型T,这样我们在外部调用的时候,拿到的返回结果就是我们传入到BackgroundWorkerEx<T>
泛型类中的T
类型,而不需要使用as
进行转换; 注:因为原生没有停止相关事件,所以自定义异步停止的事件参数使用的是DoWorkEventArgs<T>
public class DoWorkEventArgs<T> : DoWorkEventArgs
{
public new T Argument { get; set; }
public new T Result { get; set; }
public DoWorkEventArgs(object argument) : base(argument)
{
Argument = (T)argument;
}
}
public class RunWorkerCompletedEventArgs<T> : RunWorkerCompletedEventArgs
{
public new T Result { get; set; }
public RunWorkerCompletedEventArgs(object result, Exception error, bool cancelled) : base(result, error, cancelled)
{
Result = (T)result;
}
}
接着我们需要去定义事件,参数使用以上定义的泛型类
public delegate void DoWorkEventHandler(DoWorkEventArgs<T> Argument);
/// <summary>
/// StartAsync
/// </summary>
public event DoWorkEventHandler DoWork;
public delegate void StopEventHandler(DoWorkEventArgs<T> Argument);
/// <summary>
/// StopAsync
/// </summary>
public event StopEventHandler WorkStoped;
public delegate void RunWorkCompletedEventHandler(RunWorkerCompletedEventArgs<T> Argument);
/// <summary>
/// FinishAsync
/// </summary>
public event RunWorkCompletedEventHandler RunWorkCompleted;
定义全局的字段
private BackgroundWorker _mWorker = null;
异步操作必要;
private T _mWorkArg = default(T);
操作传递进来的参数类并且返回到外部
private Timer _mTimer;
定时器检测自定义进度条控件属性IsStop
是否为true
,并且动态修改进度条消息
private Thread _mWorkerThread = null;
异步操作在该线程中,终止时调用About()
抛出ThreadAbortException
异常,用于标记当前是停止而不是完成状态
private int _miWorkerStartDateSecond = 0;
异步消耗时间(非必要)
private int _miShowProgressCount = 0;
动态显示"."的个数(非必要)
private ProgressbarEx _mfrmProgressForm = null;
自定义进度条控件实例
/// <summary>
/// .Net BackgroundWorker
/// </summary>
private BackgroundWorker _mWorker = null;
/// <summary>
/// Whole Para
/// </summary>
private T _mWorkArg = default(T);
/// <summary>
/// Timer
/// </summary>
private Timer _mTimer = null;
/// <summary>
/// WorkingThread
/// </summary>
private Thread _mWorkerThread = null;
/// <summary>
/// Async time sec
/// </summary>
private int _miWorkerStartDateSecond = 0;
/// <summary>
/// Async time dot
/// </summary>
private int _miShowProgressCount = 0;
/// <summary>
/// ProgressbarEx
/// </summary
private ProgressbarEx _mfrmProgressForm = null;
IsBusy
返回_mWorker
的工作忙碌是否
ProgressTip
自定义进度条控件显示内容
/// <summary>
/// Express Busy
/// </summary>
public bool IsBusy
{
get
{
if (_mWorker != null)
{
return _mWorker.IsBusy;
}
return false;
}
}
/// <summary>
/// 进度条提示 默认: 正在加载数据,请稍后[{0}]{1}
/// </summary>
public string ProgressTip { get; set; } = "Elapsed Time[{0}]{1}";
**到现在,我们已经将必要的字段,属性,样式都处理完成!!! ** 接下来我们就要实现方法
方法实现
/// <summary>
/// Working
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
if (DoWork == null)
{
e.Cancel = true;
return;
}
DoWorkEventArgs<T> Argument = new DoWorkEventArgs<T>(e.Argument);
try
{
if (_mWorkerThread != null && _mWorkerThread.IsAlive)
{
_mWorkerThread.Abort();
}
}
catch (Exception)
{
Thread.Sleep(50);
}
_mWorkerThread = new Thread(a =>
{
try
{
DoWork?.Invoke(a as DoWorkEventArgs<T>);
}
catch (Exception)
{
}
});
_mWorkerThread.IsBackground = true;
_mWorkerThread.Start(Argument);
//Maybe cpu do not start thread
Thread.Sleep(20);
//Wait.....
while (_mWorkerThread.IsAlive)
{
Thread.Sleep(50);
}
e.Result = Argument.Result;
}
将全局的BackgroundWorker
实例_mWorker
相关事件取消注册,并且检查线程情况
感觉线程情况,如果线程状态为ThreadState.Aborted
意味着线程被停止了,调用停止事件,否则调用完成事件
/// <summary>
/// Completed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Worker_RunWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
if (_mfrmProgressForm != null)
{
_mfrmProgressForm.Close();
_mfrmProgressForm.Dispose();
_mfrmProgressForm = null;
}
if (_mWorker != null)
{
_mWorker.DoWork -= Worker_DoWork;
_mWorker.RunWorkerCompleted -= Worker_RunWorkCompleted;
try
{
if (_mWorkerThread != null && _mWorkerThread.IsAlive) _mWorkerThread.Abort();
}
catch (Exception) { }
}
//In timer, When stop progress will make thread throw AbortException
if (_mWorkerThread != null && _mWorkerThread.ThreadState == ThreadState.Aborted)
{
WorkStoped?.Invoke(new DoWorkEventArgs<T>(_mWorkArg));
}
else
{
RunWorkCompleted?.Invoke(new RunWorkerCompletedEventArgs<T>(e.Result, e.Error, e.Cancelled));
}
}
catch (Exception ex)
{
throw ex;
}
}
线程开始
检查消息提醒内容 , {0}{1}同于显示异步耗时和".."的个数
在定时器执行方法中,检查_mfrmProgressForm.IsStop
是否为true,这个属性标志是否被停止;true则抛出异常
_mfrmProgressForm
不为Null
则不断修改当前的内容提醒,友好化,实际可以按需处理
/// <summary>
/// Timer Start
/// </summary>
private void StartTimer()
{
//Check user ProgressTip
if (!ProgressTip.Contains("{0}"))
{
ProgressTip += "...Elapsed Time{0}{1}";
}
if (_mTimer != null) return;
//On one sec
_mTimer = new Timer(1000);
_mTimer.Elapsed += (s, e) =>
{
//progress and it''s stop flag (picture stop)|| this stop flag
if (_mfrmProgressForm != null && _mfrmProgressForm.IsStop)
{
if (_mWorker != null)
{
try
{
if (_mWorkerThread != null && _mWorkerThread.IsAlive)
{
if (_mTimer != null && _mTimer.Enabled)
{
_mTimer.Stop();
_mTimer = null;
}
_mWorkerThread.Abort();
}
}
catch (Exception) { }
}
}
if (_mfrmProgressForm != null)
{
//Callback
_mfrmProgressForm.Invoke(new Action<DateTime>(elapsedtime =>
{
DateTime sTime = elapsedtime;
//worked time
_miWorkerStartDateSecond++;
if (_mfrmProgressForm != null)
{
_mfrmProgressForm.SetProgressValue(_miWorkerStartDateSecond);
}
//.....count
_miShowProgressCount++;
if (_miShowProgressCount > 6)
{
_miShowProgressCount = 1;
}
string[] strs = new string[_miShowProgressCount];
string ProgressStr = string.Join(".", strs);
string ProgressText = string.Format(ProgressTip, _miWorkerStartDateSecond, ProgressStr);
if (_mfrmProgressForm != null)
{
_mfrmProgressForm.TipMessage = ProgressText;
}
}), e.SignalTime);
}
};
if (!_mTimer.Enabled)
{
_mTimer.Start();
}
}
**最后一步:异步开始 ** 与BackgroundWorker
用法一致,只是在最后开始了定时器和进度条控件而已
/// <summary>
/// Start AsyncWorl
/// </summary>
/// <param name="Para"></param>
public void AsyncStart(T Para)
{
//if workeven is null ,express user do not regist event
if (DoWork == null)
{
return;
}
_miWorkerStartDateSecond = 0;
_miShowProgressCount = 0;
//init
if (_mWorker != null && _mWorker.IsBusy)
{
_mWorker.CancelAsync();
_mWorker = null;
}
_mWorker = new BackgroundWorker();
//create progressbar
_mfrmProgressForm = new ProgressbarEx();
//add event
_mWorker.DoWork += Worker_DoWork;
_mWorker.RunWorkerCompleted += Worker_RunWorkCompleted;
_mWorker.WorkerReportsProgress = true;
_mWorker.WorkerSupportsCancellation = true;
//Set Whole Para
_mWorkArg = Para;
_mWorker.RunWorkerAsync(Para);
//Start timer
StartTimer();
_mfrmProgressForm.StartPosition = FormStartPosition.CenterParent;
_mfrmProgressForm.ShowDialog();
}
到这里,整个的进度条控件已经完成了!
调用
/// <summary>
/// Para Class
/// </summary>
public class ParaArg
{
public DataTable Data { get; set; }
public string Msg { get; set; }
public Exception Ex { get; set; }
}
定义全局的帮助类BackgroundWorkerEx<ParaArg> workHelper = null;
调用
if (workHelper != null || (workHelper != null && workHelper.IsBusy))
{
workHelper.Dispose();
workHelper = null;
}
if (workHelper == null)
{
workHelper = new BackgroundWorkerEx<ParaArg>();
}
workHelper.DoWork += (eve) =>
{
ParaArg args = eve.Argument;
try
{
//ToDo like Thread.Sleep(20000);
Thread.Sleep(10000);
args.Msg = "...this is bussiness code result";
throw new Exception("");
}
catch (Exception ex)
{
args.Ex = ex;
}
finally
{
eve.Result = args;
}
};
workHelper.RunWorkCompleted += (eve) =>
{
if (eve.Error != null)
{
//get .net backgroundworker exception;
//handle this exception;
//return ?
}
//get your para result
ParaArg x = eve.Result;
if (x.Ex != null)
{
//get your bussiness exception;
//handle this exception;
//return ?
}
//finially get your need;
//MayBe to do some UI hanlde and bussiness logical
string sReusltMsg = x.Msg;
};
workHelper.WorkStoped += (eve) =>
{
//if stoped ! it means no error;
//just get what you want;
ParaArg x = eve.Result as ParaArg;
btnBegin.Enabled = true;
};
//参数
ParaArg arg = new ParaArg()
{
Msg = "Msg"
};
workHelper.AsyncStart(arg);
最后
其实不管是封装的过程,还是调用,可以说完全就是BackgroundWorker
的方式,所以很多BackgroundWorker
相关的地方我都没有很详细的去说明;只要看看这个异步模型,就能够很好理解!大家有空也可以实现以下,有问题也可以详细,我比较喜欢交流技术~~~
还有一点就是这个解决方案已经放上Github上了,欢迎大家拉下来用
关于ExtJs4 笔记 和8 Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件 的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于android ListView和ProgressBar(进度条控件)的使用方法、Android ProgressBar:进度条控件、Android进度条控件progressbar使用方法详解、C# 根据BackgroundWoker异步模型和ProgressBar控件,自定义进度条控件 的相关知识,请在本站寻找。