技术看点
- 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作为只容器。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
注释不是很多,如有需要拿走不谢.