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( * Radius, * Radius)), , );
- path.AddLine(new Point(rect.X + Radius, rect.Y), new Point(rect.Right - Radius, rect.Y));
- path.AddArc(new Rectangle(new Point(rect.Right - * Radius, rect.Y), new Size( * Radius, * Radius)), , );
- path.AddLine(new Point(rect.Right, rect.Y + Radius), new Point(rect.Right, rect.Bottom - Radius));
- path.AddArc(new Rectangle(new Point(rect.Right - * Radius, rect.Bottom - * Radius), new Size( * Radius, * Radius)), , );
- 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 - * Radius), new Size( * Radius, * Radius)), , );
- 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(, 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(, );
- 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 = ;
- 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(-, -);
- 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( * Radius, * Radius)), , );
- path.AddLine(new Point(rect.X + Radius, rect.Y), new Point(rect.Right - Radius, rect.Y));
- path.AddArc(new Rectangle(new Point(rect.Right - * Radius, rect.Y), new Size( * Radius, * Radius)), , );
- path.AddLine(new Point(rect.Right, rect.Y + Radius), new Point(rect.Right, rect.Bottom - Radius));
- path.AddArc(new Rectangle(new Point(rect.Right - * Radius, rect.Bottom - * Radius), new Size( * Radius, * Radius)), , );
- 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 - * Radius), new Size( * Radius, * Radius)), , );
- 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, ), path);
- g.FillPath(new SolidBrush(Color.FromArgb(, BackColor)), path);
- }
- else
- {
- g.DrawPath(new Pen(BorderColor, ), path);
- rect.Inflate(-, -);
- g.FillPath(new SolidBrush(Color.FromArgb(, BackColor)), path);
- }
- #region 画文本
- g.SmoothingMode = SmoothingMode.AntiAlias;
- if (IconImage != null)
- {
- Rectangle rc = new Rectangle((Width - ) / , , IconSize.Width, IconSize.Height);
- g.DrawImage(IconImage, rc);
- }
- if (!string.IsNullOrEmpty(ButtonText))
- {
- using (StringFormat f = new StringFormat())
- {
- Rectangle rectTxt = new Rectangle(, (Height - ) / , Width, );
- 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;
- }
- }
注释不是很多,如有需要拿走不谢.
C#Winform 自定义透明按钮和单窗体模块化实现的更多相关文章
- c#winform自定义窗体,重绘标题栏,自定义控件学习
c#winform自定义窗体,重绘标题栏 虽然现在都在说winform窗体太丑了,但是我也能尽量让桌面应用程序漂亮那么一点点话不多说,先上图 重绘标题栏先将原生窗体设置成无边框,FormBoderSt ...
- WPF权限控制——【3】数据库、自定义弹窗、表单验证
你相信"物竞天择,适者生存"这样的学说吗?但是我们今天却在提倡"尊老爱幼,救死扶伤",帮助并救护弱势群体:第二次世界大战期间,希特勒认为自己是优等民族,劣势民族 ...
- Winform的"透明"
手头目前的一个项目(.Net4.0)中有这样一个需求:在程序中要进行视频采集,并且要在视频影像区域进行绘图编辑,对绘图能进行拉伸,拖拽和删除.从需求来看,必须得在视频影像区的上方盖一层画布才能这么操作 ...
- OC导航栏自定义返回按钮
[iOS]让我们一次性解决导航栏的所有问题 在默认情况下,导航栏返回按钮长这个样子 导航栏默认返回按钮 导航栏左上角的返回按钮,其文本默认为上一个ViewController的标题,如果上一个Vi ...
- 自定义常用input表单元素三:纯css实现自定义Switch开关按钮
自定义常用input表单元素的第三篇,自定义一个Switch开关,表面上看是和input没关系,其实这里采用的是checkbox的checked值的切换.同样,采用css伪类和"+" ...
- VB6史无前例的子类化之透明按钮
[原创文章,转发请保留版权信息] 作者:mezstd 文章地址:http://www.cnblogs.com/imez/p/3299728.html 效果图: 请原谅笔者无耻地称之为史无前例,至少在笔 ...
- WPF 无边框透明按钮
在实际开发过程中,有时候要设置一个无边框的按钮,或者无边框的透明按钮. 按钮效果如下: 1.当你应用telerik组件中的Button时,这个直接就可以设置 telerik:StyleManager. ...
- Mono自定义图片按钮
首先,我们编写一个MyImageButton类,继承自LinearLayout public class MyPhoneImageButton:LinearLayout { private Image ...
- SharePoint 2013 关于自定义显示列表表单的bug
1.在SharePoint 2013中,我们隐藏列表Dispform页面的ListFormWebPart部件,转而使用自定义显示列表表单进行展示,因为这样更容易定制我们需要的显示: 2.之后发现文件夹 ...
随机推荐
- Java爬虫--Https绕过证书
https网站服务器都是有证书的. 是由网站自己的服务器签发的,并不被浏览器或操作系统广泛接受. 在使用CloseableHttpClient时经常遇到证书错误(知乎的网站就是这样) 现在需要SSL绕 ...
- 谈谈单元測试之(二):測试工具 JUnit 3
前言 上一篇文章<为什么要进行烦人的单元測试?>讨论了一下现阶段软件开发中,程序猿们測试情况的现状.这篇文章中,我打算介绍一下单元測试的工具(插件).而且推荐大家以后在开发中,真正的用上单 ...
- iWeb峰会(HTML5峰会)2015年7月19日上海站会后感想
上周日专门从南京跑到上海參加了iWeb峰会(HTML5峰会),感觉这一天去的挺值的.几个演讲都挺精彩,干货不少啊. 总体感觉随着2014年HTML5标准的终于定稿,最近HTML5 ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...
- UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)
题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...
- 关于使用Xcode9.0使用[UIImage imageNamed:]返回null的问题
最近升级Xcode9.0,没少折腾,再加上iOS11出现的问题,又要适配一些奇怪的问题.这都没啥,但是如果Xcode出问题,那问题可真是难找.因为习惯的操作潜意思的告诉自己这样做是不会错的. 在Xco ...
- [array] leetcode - 34. Search for a Range - Medium
leetcode - 34. Search for a Range - Medium descrition Given an array of integers sorted in ascending ...
- xml文件解析(使用解析器)
一.Xml解析,解析xml并封装到list中的javabean中 OM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在 ...
- 初探XRebel
一.什么是XRebel? 1.介绍 XRebel 是不间断运行在 web 应用的交互式分析器.可以看到网页上的每一个操作在前端以及服务端.数据库.网络传输都花费多少时间,当发现问题会在浏览器中显示警告 ...
- ExperDot的博客目录导航
最近活动 我更新了博客!粒子系统:从零开始画一棵树 Github:[ UWP ] [ JavaScript ] 自然编程 奇幻元纪 上帝创世篇:如何画一颗静态树 女娲补天篇:仿人工拼接碎片 吴刚伐桂 ...