技術看點
- 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; } }
注釋不是很多,如有需要拿走不謝.
