zoukankan      html  css  js  c++  java
  • 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);
            }

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

  • 相关阅读:
    选择和冒泡
    马尔科夫模型
    网络IO
    java项目相对路径
    MySQL 数据类型
    基于 Token 的身份验证方法
    git 打标签
    git版本回退
    robotframework使用过程中的一些总结
    robotframework安装robotframework-requests库遇到的几种问题
  • 原文地址:https://www.cnblogs.com/hejoy91/p/13598779.html
Copyright © 2011-2022 走看看