一直想加一个进度条到XAF的工程中去,最后发现两条途径:
1.自定义模板,加入进度条;
2.动态弹出一个进度条;
自定义模板就不说了,可以参照官方文档的例子做,下面说说弹出进度条,如图:
这个例子是我模仿FeatureCenter部分代码做的,下面两个文件(LongOperationController.cs和ProgressForm.cs)的代码无须更改,可直接使用。
LongOperationController.cs的源码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.ExpressApp;
using System.ComponentModel;
namespace FunSolution.Module
{
public interface IProgressControl : IDisposable
{
void ShowProgress(BackgroundWorker worker);
}
public abstract class LongOperationController : ViewController
{
private IProgressControl progressControl;
private BackgroundWorker _worker;
public BackgroundWorker Worker
{
private set { _worker = value; }
get { return _worker; }
}
private void Work_Completed(object sender,RunWorkerCompletedEventArgs e)
{
OnOperationCompleted();
progressControl.Dispose();
progressControl = null;
((BackgroundWorker)sender).RunWorkerCompleted -= new RunWorkerCompletedEventHandler(Work_Completed);
((BackgroundWorker)sender).Dispose();
}
protected abstract void DoWorkCore(object sender, DoWorkEventArgs e);
protected abstract IProgressControl CreateProgressControl();
protected virtual void OnOperationCompleted()
{
View.ObjectSpace.Refresh();
if (OperationCompleted != null)
{
OperationCompleted(this, EventArgs.Empty);
}
}
protected void StartLongOperation()
{
Worker = new BackgroundWorker();
Worker.WorkerReportsProgress = true;
Worker.WorkerSupportsCancellation = true;
Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Work_Completed);
Worker.DoWork += new DoWorkEventHandler(DoWorkCore);
progressControl = CreateProgressControl();
progressControl.ShowProgress(Worker);
Worker.RunWorkerAsync();
}
protected void RaiseProcessChanged(int percentage)
{
Worker.ReportProgress(percentage);
}
protected bool CancellationPending
{
get { return Worker.CancellationPending; }
}
//子类可订阅也可不订阅
public event EventHandler OperationCompleted;
}
}
下面是ProgressForm.cs的源码,负责显示部分:
using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.XtraEditors;
using System.Windows.Forms;
using DevExpress.ExpressApp;
using System.ComponentModel;
using System.Drawing;
using FunSolution.Module;
namespace FunSolution.Module.Win
{
public class ProgressForm : IProgressControl {
public const string FormName = "ProgressForm";
private XtraForm form;
private ProgressBarControl progressBar = new ProgressBarControl();
private SimpleButton cancelButton = new SimpleButton();
private Label label = new Label();
private BackgroundWorker worker;
private int minimumProgressValue;
private int maximumProgressValue;
private string progressFormCaption;
private delegate void UpdateProgressFormDelegate(int value, string message);
private void CreateProgressForm() {
form = new XtraForm();
form.Name = FormName;
form.Width = 350;
form.Height = 125;
form.StartPosition = FormStartPosition.CenterScreen;
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.ControlBox = false;
form.ShowInTaskbar = false;
label.Parent = form;
label.Location = new Point(10, 10);
label.Size = new Size(form.ClientSize.Width - 20, 13);
progressBar.Parent = form;
progressBar.Location = new Point(10, 30);
progressBar.Name = "progressBar";
progressBar.Size = new Size(form.ClientSize.Width - 20, 15);
progressBar.Properties.Minimum = minimumProgressValue;
progressBar.Properties.Maximum = maximumProgressValue;
progressBar.Properties.Step = 1;
cancelButton.Parent = form;
cancelButton.DialogResult = DialogResult.Cancel;
cancelButton.Size = new Size(75, 23);
cancelButton.Location = new Point((form.Width - cancelButton.Width) / 2, 55);
cancelButton.Text = "&Cancel";
cancelButton.Click += new EventHandler(cancelButton_Click);
cancelButton.LostFocus += new EventHandler(DoOnFormLostFocus);
form.CancelButton = cancelButton;
form.Text = progressFormCaption;
}
private void DoOnFormLostFocus(object sender, EventArgs e) {
form.Focus();
}
private void LongOperation_Completed(object sender, RunWorkerCompletedEventArgs e) {
if(form != null) {
form.Invoke(new MethodInvoker(form.Close));
}
}
private void UpdateProgressForm(int value, string message) {
progressBar.EditValue = value;
progressBar.Update();
label.Text = message;
}
private void LongOperation_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int value = e.ProgressPercentage;
if(form != null) {
form.Invoke(new UpdateProgressFormDelegate(UpdateProgressForm), new object[] { value, null });
}
}
private void cancelButton_Click(object sender, EventArgs e) {
if (worker.WorkerSupportsCancellation == true)
{
worker.CancelAsync();
}
}
protected ProgressForm(int minimum, int maximum)
: this("", minimum, maximum) {
}
public ProgressForm(string caption, int minimum, int maximum) {
this.progressFormCaption = caption;
this.minimumProgressValue = minimum;
this.maximumProgressValue = maximum;
CreateProgressForm();
}
public ProgressForm()
: this(0, 100) {
}
public void Dispose() {
label = null;
cancelButton.LostFocus -= new EventHandler(DoOnFormLostFocus);
this.worker.ProgressChanged -= new ProgressChangedEventHandler(LongOperation_ProgressChanged);
this.worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(LongOperation_Completed);
if(form != null) {
form.Invoke(new MethodInvoker(form.Dispose));
form = null;
}
}
public void ShowProgress(BackgroundWorker worker) {
form.Show();
this.worker = worker;
this.worker.ProgressChanged += new ProgressChangedEventHandler(LongOperation_ProgressChanged);
this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LongOperation_Completed);
}
}
}
接下来就是自己新加的ViewController,添加一个ViewController使它继承LongOperationController,并重写以下方法:
protected override void DoWorkCore(object sender, DoWorkEventArgs e)
protected override IProgressControl CreateProgressControl()
DoWorkCore是要进行的耗时的具体操作,CreateProgressControl创建进度条窗体。
另外,添加一个Action调用继承而来的StartLongOperation。
public partial class ViewController1 : LongOperationController
{
public ViewController1()
{
InitializeComponent();
RegisterActions(components);
}
protected override void DoWorkCore(object sender, DoWorkEventArgs e)
{
int i=0;
while(i++<100){
if (CancellationPending == true)
break;
Thread.Sleep(50);
this.RaiseProcessChanged(i);
}
}
protected override IProgressControl CreateProgressControl()
{
return new ProgressForm("操作进行中", 0, 100);
}
private void simpleAction1_Execute(object sender, SimpleActionExecuteEventArgs e)
{
this.StartLongOperation();
}
}