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);
            }

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

  • 相关阅读:
    KnockoutJS 3.X API 第五章 高级应用(4) 自定义处理逻辑
    KnockoutJS 3.X API 第五章 高级应用(3) 虚拟元素绑定
    KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定
    KnockoutJS 3.X API 第五章 高级应用(1) 创建自定义绑定
    KnockoutJS 3.X API 第四章(14) 绑定语法细节
    KnockoutJS 3.X API 第四章(13) template绑定
    KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定
    KnockoutJS 3.X API 第四章 表单绑定(11) options绑定
    KnockoutJS 3.X API 第四章 表单绑定(10) textInput、hasFocus、checked绑定
    KnockoutJS 3.X API 第四章 表单绑定(9) value绑定
  • 原文地址:https://www.cnblogs.com/hejoy91/p/13598779.html
Copyright © 2011-2022 走看看