C#Winform 自定義透明按鈕和單窗體模塊化實現


技術看點

  • WinForm自定義控件的使用
  • WinForm單窗體應用如何模塊化

需求及效果

又來一波 C# GDI自定義控件show 。這個控件已經使用幾年了,最近找出來重構一下。原來是沒有邊框的,那么導致導航的功能不是很突出。本來想加個效果:在執行單擊時顯示Loading動畫,在執行完單擊事件后恢復原樣。這就是網頁里見到的局部刷新,Ajax常用的場景。無奈要下班了,還沒弄出來。需求來自幾年前一個智能儲物櫃項目,人機界面有個美工設計好的效果圖,為了省事和通用,需要一個透明的按鈕來實現導航的任務。就是控件只是設計時可見,運行時不可見。

 

 

關鍵點說明

1)、GraphicsPath實現矩形的圓角羽化處理

 

 using (GraphicsPath path = new GraphicsPath())
            {
                #region 羽化,圓角處理
                path.StartFigure();
                path.AddArc(new Rectangle(new Point(rect.X, rect.Y), new Size(2 * Radius, 2 * Radius)), 180, 90);
                path.AddLine(new Point(rect.X + Radius, rect.Y), new Point(rect.Right - Radius, rect.Y));
                path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Y), new Size(2 * Radius, 2 * Radius)), 270, 90);
                path.AddLine(new Point(rect.Right, rect.Y + Radius), new Point(rect.Right, rect.Bottom - Radius));
                path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 0, 90);
                path.AddLine(new Point(rect.Right - Radius, rect.Bottom), new Point(rect.X + Radius, rect.Bottom));
                path.AddArc(new Rectangle(new Point(rect.X, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 90, 90);
                path.AddLine(new Point(rect.X, rect.Bottom - Radius), new Point(rect.X, rect.Y + Radius));
                path.CloseFigure();
                #endregion 
                

要點就是畫幾段弧線和矩形連接起來。透明就是用了Color.FromArgb加上透明度,然后填充GraphicsPath形成透明區域。

g.FillPath(new SolidBrush(Color.FromArgb(153, BackColor)), path);

2)、單窗體應用如何模塊化 

窗體只有一個,但操作界面好多個,由於是無人值守的應用。那么老是切換窗體操作是非常不方便的。工作區域是一個容器Panel,把每個操作界面定義成一個Panel作為只容器。

 public partial class DepositBizPanel : UserControl
    {
        private BackgroundStyle backgroundStyle = BackgroundStyle.Green;
        /// <summary>
        /// 主題風格
        /// </summary>
        public BackgroundStyle BackgroundStyle
        {
            get { return backgroundStyle; }
            set
            {
                backgroundStyle = value;
                switch (value)
                {
                    case GreenlandExpressBox.BackgroundStyle.Blue:
                        BackgroundImage = Properties.Resources.jbblue;
                        break;
                    case GreenlandExpressBox.BackgroundStyle.Orange:
                        BackgroundImage = Properties.Resources.jborange;
                        break;
                    case GreenlandExpressBox.BackgroundStyle.Green:
                        BackgroundImage = Properties.Resources.jbgreen;
                        break;
                }
                Invalidate();
            }
        }

        public Panel ParentPanel
        {
            get;
            set;
        }

        public Bitmap QR_Barcode
        {
            get { return (Bitmap)pbxBarcode.Image; }
            set { pbxBarcode.Image = value; }
        }

        public DialogResult PanelDiagResult
        {
            get;
            set;
        }

        public DepositBizPanel(Panel parent, Bitmap barcode, BackgroundStyle style)
        {
            InitializeComponent();
            DoubleBuffered = true;
            ParentPanel = parent;
            QR_Barcode = barcode;
            BackgroundStyle = style;
        }       

        private void btnback_Click(object sender, EventArgs e)
        {
            foreach (Control panel in ParentPanel.Controls)
            {
                if (panel is DepositBizPanel)
                {
                    ParentPanel.Controls.Remove(panel);
                    PanelDiagResult = DialogResult.Cancel;
                    break;
                }
            }
        }

        private void btnprocessnext_Click(object sender, EventArgs e)
        {
            foreach (Control panel in ParentPanel.Controls)
            {
                if (panel is DepositBizPanel)
                {
                    ParentPanel.Controls.Remove(panel);
                    PanelDiagResult = DialogResult.OK;
                    break;
                }
            }
        }
    }
人機操作界面例子

 

透明按鈕自定義控件全部代碼

自定義按鈕:

/// <summary>
    /// Cool透明自定義按鈕
    /// </summary>
    public partial class CoolTransparentButton : UserControl
    {
        private Size iconSize = new Size(32, 32);
        public Size IconSize
        {
            get
            {
                return iconSize;
            }
            set
            {
                iconSize = value;
                Invalidate();
            }
        }
        private string _ButtonText;
        public string ButtonText
        {
            get { return _ButtonText; }
            set
            {
                _ButtonText = value;
                Invalidate();
            }
        }
        protected Image _IconImage;
        public Image IconImage
        {
            get
            {
                return _IconImage;
            }
            set
            {
                _IconImage = value;
                Invalidate();
            }
        }
        private bool _FocseActived = false;
        private Color _BorderColor = Color.White;
        public Color BorderColor
        {
            get
            {
                return _BorderColor;
            }
            set
            {
                _BorderColor = value;
                Invalidate();
            }
        }
        private int _Radius = 12;
        public int Radius
        {
            get
            {
                return _Radius;
            }
            set
            {
                _Radius = value;
                Invalidate();
            }
        }
        private bool ifDrawBorderWhenLostFocse = true;
        /// <summary>
        /// 失去焦點是否畫邊框
        /// </summary>
        public bool IfDrawBorderWhenLostFocse
        {
            get
            {
                return ifDrawBorderWhenLostFocse;
            }
            set
            {
                ifDrawBorderWhenLostFocse = value;
                Invalidate();
            }
        }
        /// <summary>
        /// 是否處於激活狀態(焦點)
        /// </summary>
        public bool FocseActived
        {
            get { return _FocseActived; }
            set
            {
                _FocseActived = value;
                Invalidate();
            }
        }          
        public CoolTransparentButton()
        {
            DoubleBuffered = true;
            BackColor = Color.Transparent;
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.Opaque, false);
            UpdateStyles(); 
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            var rect = ClientRectangle;
            rect.Inflate(-1, -1);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            using (GraphicsPath path = new GraphicsPath())
            {
                #region 羽化,圓角處理
                path.StartFigure();
                path.AddArc(new Rectangle(new Point(rect.X, rect.Y), new Size(2 * Radius, 2 * Radius)), 180, 90);
                path.AddLine(new Point(rect.X + Radius, rect.Y), new Point(rect.Right - Radius, rect.Y));
                path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Y), new Size(2 * Radius, 2 * Radius)), 270, 90);
                path.AddLine(new Point(rect.Right, rect.Y + Radius), new Point(rect.Right, rect.Bottom - Radius));
                path.AddArc(new Rectangle(new Point(rect.Right - 2 * Radius, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 0, 90);
                path.AddLine(new Point(rect.Right - Radius, rect.Bottom), new Point(rect.X + Radius, rect.Bottom));
                path.AddArc(new Rectangle(new Point(rect.X, rect.Bottom - 2 * Radius), new Size(2 * Radius, 2 * Radius)), 90, 90);
                path.AddLine(new Point(rect.X, rect.Bottom - Radius), new Point(rect.X, rect.Y + Radius));
                path.CloseFigure();
                #endregion 
                if (!FocseActived)
                {
                    if (ifDrawBorderWhenLostFocse)
                        g.DrawPath(new Pen(Color.Gray, 1), path);
                    g.FillPath(new SolidBrush(Color.FromArgb(66, BackColor)), path);
                }
                else
                {
                    g.DrawPath(new Pen(BorderColor, 1), path);
                    rect.Inflate(-1, -1);
                    g.FillPath(new SolidBrush(Color.FromArgb(153, BackColor)), path);
                }
                #region 畫文本
                g.SmoothingMode = SmoothingMode.AntiAlias;
                if (IconImage != null)
                {
                    Rectangle rc = new Rectangle((Width - 32) / 2, 16, IconSize.Width, IconSize.Height);
                    g.DrawImage(IconImage, rc);
                }
                if (!string.IsNullOrEmpty(ButtonText))
                {
                    using (StringFormat f = new StringFormat())
                    {
                        Rectangle rectTxt = new Rectangle(0, (Height - 18) / 2, Width, 36);
                        f.Alignment = StringAlignment.Center;// 水平居中對齊 
                        f.LineAlignment = StringAlignment.Center;   // 垂直居中對齊 
                        f.FormatFlags = StringFormatFlags.NoWrap;// 設置為單行文本 
                        SolidBrush fb = new SolidBrush(this.ForeColor); // 繪制文本 
                        e.Graphics.DrawString(ButtonText, new Font("微軟雅黑", 16F, FontStyle.Bold), fb, rectTxt, f);
                    }
                }
                #endregion 
            }
        }
        protected override void OnMouseHover(EventArgs e)
        {
            FocseActived = true;
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            FocseActived = false;
        }
        protected override void OnEnter(EventArgs e)
        {
            FocseActived = true;
        }
        protected override void OnLeave(EventArgs e)
        {
            FocseActived = false;
        } 
    }

注釋不是很多,如有需要拿走不謝.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM