从零开始搭建一个GIS开发小框架(九)——GMap.Net组件WPF版本进度条效果

1.概述

今天借GIS项目实现一个进度条效果,这个效果在各种管理系统中是最常见的一个效果,特别是在处理某个任务消耗的时间过长的场景,可以避免UI假死,提高用户体验。我这次用的POI数据大概有90W条,这个目录树是我为了练手,故意拆成五层的,其实从第三层到第五层原本是放在一个字段里的string型POI类型描述,将它拆解成三层树结构时损耗了部分性能,到最下面一层(图标是感叹号)类型,大概有5700多个叶子节点,加载这个资源目录树需要一段时间,这里用委托实现页面传值+BackgroundWorker实现异步弹框进度条效果。我原来在winform里面实现过,但是WPF框架里还没做过,拿这个练练手,为今后的工(qiu)作(zhi)任(mian)务(shi)做好技术储备。

委托是一种引用类型,它是函数指针的托管版本。

2.运行效果

废话不多说直接上图。示例只用了一个区的数据,读取全市数据太慢了。
在这里插入图片描述

GMap.Net.WPF演示进度条效果

3.委托的思路

委托页面传值是委托的一个最简单应用场景,大家可以拿来练练手,边做边理解一下委托的概念,我把委托传值用法的大致思路画了一个草稿,见下图,希望对大家理解有帮助。代码最后那个“百分比处理”的代码是我在网上找的一个觉得比较别致的写法,纯属收藏这段代码,实际处理百分比不需要那么啰嗦,求x的时候不乘以100,直接加上百分符号就完事了。
在这里插入图片描述

// 文本框赋值方法 的委托属性
private LoadDataEventHandler _loadDataSubWindowDel;
BackgroundWorker worker = null;

/// <summary>
/// 
/// </summary>
/// <param name="typeString"></param>
/// <param name="adname"></param>
/// <param name="del"></param>
public WindowForDataLoadProcess(string typeString, string adname, LoadDataEventHandler del)
{
    InitializeComponent();

    worker = new BackgroundWorker();
    //异步取消 需要增加这个 不然取消失效
    worker.WorkerSupportsCancellation = true;
    //支持报告进度
    worker.WorkerReportsProgress = true;
    //注册滚动条事件
    worker.ProgressChanged += ProgessChangedInit;
    //注册任务
    worker.DoWork += DoWorkInit;
    //任务完毕触发
    worker.RunWorkerCompleted += CompleteWorkInit;

    StartKeyCompareRunning(typeString, adname);   //这个是我的启动方法

    this._loadDataSubWindowDel = del;
}

#region BackgroundWorker 多线程

/// <summary>
/// 第一次打开Form
/// </summary>
private void StartKeyCompareRunning(string typeString, string adname)
{
    string[] para = { typeString, adname };
    worker.RunWorkerAsync(para);
}

//调用 RunWorkerAsync 时发生
public void DoWorkInit(object sender, DoWorkEventArgs e)
{
    if (worker.CancellationPending) //判断是否取消操作
    {
        e.Cancel = true; //这里才真正取消 
        return;
    }
    else
    {
        string[] receive = e.Argument as string[];
        e.Result = LoadData(worker, e, receive);   //LoadData就是读取数据并处理进度条report事件的自定义方法
    }
}

//调用 ReportProgress 时发生
public void ProgessChangedInit(object sender, ProgressChangedEventArgs e)
{
    //将异步任务进度的百分比赋给进度条
    this.progressBar1.Value = e.ProgressPercentage;
    this.Label1.Content = (string)e.UserState;
}

/// <summary>
/// 当后台操作已完成、被取消或引发异常时发生
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void CompleteWorkInit(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        System.Windows.MessageBox.Show("Progess is interrupted!");
    }
    else if (e.Error != null)
    {
        System.Windows.MessageBox.Show("Worker exception: " + e.Error.ToString());
    }
    else
    {
        try
        {
            FormMainProgressBarResult re = (FormMainProgressBarResult)e.Result;
            this.Close();

            //委托返回值给父窗口
            _loadDataSubWindowDel(re);  //委托传值回主界面
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

#region load数据

/// <summary>
/// 组装树的数据集
/// </summary>
private FormMainProgressBarResult LoadData(BackgroundWorker worker, DoWorkEventArgs e, string[] paraArray)
{
    FormMainProgressBarResult iRel = new FormMainProgressBarResult();

    try
    {
        组装DataTable dtLevel5 数据集(方法略),dtLevel5是第五层叶子节点
        
        dtLevel5 装进dt里,dt是总数据集
		foreach (DataRow d5 in dtLevel5.Rows)
		{
			DataRow dr5 = dt.NewRow();
			dr5["id"] = d5["Name"];
			.....
			dt.Rows.Add(dr5);  
		}
		
        //进度条计算
        index = index + dtLevel5.Rows.Count;
        int x = (int)Math.Floor((double)((index + 1) * 100 / AllRows));
        //百分比处理
        System.Globalization.NumberFormatInfo provider = new System.Globalization.NumberFormatInfo();
        provider.PercentDecimalDigits = 0;   //小数点保留几位数.
        provider.PercentPositivePattern = 0; //百分号出现在何处.
        double result = (double)x/100;       //一定要用double类型.
        report_message = result.ToString("P", provider);

        worker.ReportProgress(x, report_message);

        组装dt完毕后放进返回值
    
        iRel.ResultDataTable = dt;
        iRel.ResultString = "ok";
        iMsgRel = 1;
        return iRel;
    }
    catch (Exception ex)
    {
        iRel.ResultDataTable = null;
        iRel.ResultString = ex.Message;
        return iRel;
    }

}
#endregion


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiangcns

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值