• C#自定义加载框、等待框、加载层


    自制简单实用加载层

    1.主要方式就是通过graphics围绕中心点绘制N个小圆实现动态的效果,一圈之后变换颜色继续绘制。

    主要用到graphics的TranslateTransform、RotateTransform方法,代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace FormLoading.Dialog
    {
        public enum EMLoadingType { Small, Middle, Large}
        public partial class FormLoading : BaseDialog
        {
            public Point ptOrigin = new Point(0, 0);
            private int offset = 30;
            private int angle = 0;
            private int ConstAngle = 36;
            private int CircleWidth = 20;
    
            private Pen pLight = new Pen(Color.LightBlue, 2f);
            private Brush bLight = new SolidBrush(Color.LightBlue);
            private Brush bDark = new SolidBrush(Color.SkyBlue);
            private EMLoadingType loadType = EMLoadingType.Middle;
            public bool Finished { get; set; } = false;
            public bool Success { get; set; } = false;
            public string ResultStr { get; set; }
            public FormLoading()
            {
                InitializeComponent();
            }
            public void SetLoading(EMLoadingType type,string title,string tips)
            {
                ShowTips(tips);
                TitleText = title;
                loadType = type;
            }
            public void EndLoading(bool success)
            {
                tmLoading.Enabled = false;
                this.Finished = true;
                this.Success = success;
                if(this.Visible == true)
                    this.Close();
            }
            public void ShowTips(string tips)
            {
                labTips.Text = tips;
            }
            private void DrawCircle(Graphics g, Brush b, Pen p)
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                RectangleF rectStart = new RectangleF();
                rectStart.X = ptOrigin.X + offset;
                rectStart.Y = ptOrigin.Y - CircleWidth / 2;
                rectStart.Width = CircleWidth;
                rectStart.Height = CircleWidth;
                //g.DrawEllipse(p, rectStart);
                g.FillEllipse(b, rectStart);
            }
    
            private void tmLoading_Tick(object sender, EventArgs e)
            {
                Graphics g = this.pnlForm.CreateGraphics();
                Brush b;
                if (angle > 720 - ConstAngle)
                    angle = 0;
                if (angle <= 360 - ConstAngle)
                    b = bLight;
                else
                    b = bDark;
                g.TranslateTransform(Width / 2, Height / 2);
                g.RotateTransform(angle);
                DrawCircle(g, b, pLight);
                angle += ConstAngle;
                g.Dispose();
                
            }
            private void btnSmall_Click(object sender, EventArgs e)
            {
                Start_SmallLoading();
            }
            
            private void btnMiddle_Click(object sender, EventArgs e)
            {
                Start_MiddleLoading();
            }
    
            private void btnLarge_Click(object sender, EventArgs e)
            {
                Start_LargeLoading();
            }
            private void Start_SmallLoading()
            {
                tmLoading.Enabled = false;
                Graphics g = this.pnlForm.CreateGraphics();
                g.Clear(SystemColors.Control);
                g.Dispose();
    
                angle = 0;
                offset = 20;
                ConstAngle = 36;
                CircleWidth = 13;
                tmLoading.Enabled = true;
            }
            private void Start_MiddleLoading()
            {
                tmLoading.Enabled = false;
                Graphics g = this.pnlForm.CreateGraphics();
                g.Clear(SystemColors.Control);
                g.Dispose();
    
                angle = 0;
                offset = 30;
                ConstAngle = 36;
                CircleWidth = 20;
                tmLoading.Enabled = true;
            }
            private void Start_LargeLoading()
            {
                tmLoading.Enabled = false;
                Graphics g = this.pnlForm.CreateGraphics();
                g.Clear(SystemColors.Control);
                g.Dispose();
    
                angle = 0;
                offset = 40;
                ConstAngle = 36;
                CircleWidth = 25;
                tmLoading.Enabled = true;
            }
    
            private void FormLoading_Shown(object sender, EventArgs e)
            {
                labTips.BackColor = SystemColors.Control;
                switch (loadType)
                {
                    case EMLoadingType.Small:
                        Start_SmallLoading();
                        break;
                    case EMLoadingType.Middle:
                        Start_MiddleLoading();
                        break;
                    case EMLoadingType.Large:
                        Start_LargeLoading();
                        break;
                }
            }
        }
    }

    效果图如下:

    2. 上面只是实现了加载层的效果,具体使用需要调用相应方法用模态方式展示,并在后台用线程完成自己的耗时操作,然后关闭加载层,中间可以用invoke方法回显具体进度信息。方法如下:

    //owner:主线程UIcontrol,Application.OpenForms["xxx"]就可以,param是线程处理自己的耗时业务参数
    public
    static void DownLoadDataCallBack(Control owner, FormLoading loadingFrom, object param) { Action EndLoadingEvent; Action<string> ShowTipsEvent; bool success = false; string resultStr = ""; void ExecuteTrd() { //这里dataRlt采用Tuple返回<bool,string>两个返回结果方法好用! var dataRlt = DownloadXXXX(param); success = dataRlt.Item1; resultStr = dataRlt.Item2; owner.Invoke(EndLoadingEvent); } void EndLoading() { loadingFrom.ResultStr = resultStr; loadingFrom.EndLoading(success); } void SetTips(string tips) { loadingFrom.ShowTips(tips); } EndLoadingEvent = EndLoading; ShowTipsEvent = SetTips; if (loadingFrom != null && param != null) { Thread trd = new Thread(ExecuteTrd); trd.Start(); } }

    3.下面是封装的弹出加载框方法,调用就可以显示。

    /// <summary>
            /// 统一弹出加载框方法
            /// </summary>
            /// <param name="owner">UI窗体</param>
            /// <param name="title">窗体名称</param>
            /// <param name="tips">加载显示信息</param>
            /// <param name="callBack">业务回调方法(耗时)</param>
            /// <param name="param">业务回调参数</param>
            /// <param name="type">加载圆大小</param>
            /// <returns></returns>
            public Tuple<bool,string> ShowLoadingTips(Control owner, string title, string tips, Action<Control, FormLoading, object> callBack,
                object param, EMLoadingType type = EMLoadingType.Middle)
            {
                Logger.Debug("ShowLoadingTips");
                FormLoading loadingDialog = new FormLoading();
                loadingDialog.SetLoading(type, title, tips);
                if(callBack != null)
                    callBack(owner, loadingDialog, param);
                if(loadingDialog != null && !loadingDialog.Finished)
                    loadingDialog.ShowDialog();
                return new Tuple<bool, string>(loadingDialog.Success,loadingDialog.ResultStr);
            }

    不错的业务耗时解决方案^_^。

  • 相关阅读:
    JAVA中 ReentrantReadWriteLock读写锁详系教程,包会
    传统企业的精益转型之路
    什么时候可以使用极限编程?
    “懒蚂蚁”效应在产品开发过程中的应用
    Vue.config.js配置 最新可用版本
    如何查找一个为NULL的MYSQL字段
    MYSQL 50 基础题 (转载)
    记录一下第一次写 50行 SQL代码
    jwtUtils顾名思意
    对于我们程序员来说,基本面是什么呢?
  • 原文地址:https://www.cnblogs.com/hejoy91/p/13598779.html
Copyright © 2020-2023  润新知