(七十八)c#Winform自定义控件-倒影组件
官网
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492 
来都来了,点个【推荐】再走吧,谢谢
NuGet
Install-Package HZH_Controls
目录
https://www.cnblogs.com/bfyx/p/11364884.html
用处及效果

准备工作
GDI+画图,不了解先百度
开始
思路:
控件扩展属性,在组件中对需要显示倒影的控件的父控件添加Paint事件,在Paint事件中绘制控件,并旋转180,然后画到父控件上,然后再覆盖一层渐变色,完美。
添加一个类ShadowComponent 继承Component,实现 IExtenderProvider接口,扩展属性
代码比较少,直接放上来了
/// <summary>
/// The m control cache
/// </summary>
Dictionary<Control, bool> m_controlCache = new Dictionary<Control, bool>(); #region 构造函数 English:Constructor
/// <summary>
/// Initializes a new instance of the <see cref="ShadowComponent" /> class.
/// </summary>
public ShadowComponent()
{ } /// <summary>
/// Initializes a new instance of the <see cref="ShadowComponent" /> class.
/// </summary>
/// <param name="container">The container.</param>
public ShadowComponent(IContainer container)
: this()
{
container.Add(this);
}
#endregion /// <summary>
/// 指定此对象是否可以将其扩展程序属性提供给指定的对象。
/// </summary>
/// <param name="extendee">要接收扩展程序属性的 <see cref="T:System.Object" />。</param>
/// <returns>如果此对象可以扩展程序属性提供给指定对象,则为 true;否则为 false。</returns>
public bool CanExtend(object extendee)
{
if (extendee is Control && !(extendee is Form))
return true;
return false;
} /// <summary>
/// Gets the show shadow.
/// </summary>
/// <param name="control">The control.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
[Browsable(true), Category("自定义属性"), Description("是否显示倒影"), DisplayName("ShowShadow"), Localizable(true)]
public bool GetShowShadow(Control control)
{
if (m_controlCache.ContainsKey(control))
return m_controlCache[control];
else
return false;
} /// <summary>
/// Sets the show shadow.
/// </summary>
/// <param name="control">The control.</param>
/// <param name="isShowShadow">if set to <c>true</c> [is show shadow].</param>
public void SetShowShadow(Control control, bool isShowShadow)
{
control.ParentChanged += control_ParentChanged;
m_controlCache[control] = isShowShadow;
} /// <summary>
/// Handles the ParentChanged event of the control control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void control_ParentChanged(object sender, EventArgs e)
{
Control control = sender as Control;
if (control.Parent != null && m_controlCache[control])
{
if (!lstPaintEventControl.Contains(control.Parent))
{
lstPaintEventControl.Add(control.Parent);
Type type = control.Parent.GetType();
System.Reflection.PropertyInfo pi = type.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
pi.SetValue(control.Parent, true, null);
control.Parent.Paint += Parent_Paint;
}
}
} /// <summary>
/// The LST paint event control
/// </summary>
List<Control> lstPaintEventControl = new List<Control>();
/// <summary>
/// The shadow height
/// </summary>
private float shadowHeight = 0.3f; /// <summary>
/// Gets or sets the height of the shadow.
/// </summary>
/// <value>The height of the shadow.</value>
[Browsable(true), Category("自定义属性"), Description("倒影高度,0-1"), Localizable(true)]
public float ShadowHeight
{
get { return shadowHeight; }
set { shadowHeight = value; }
}
/// <summary>
/// The BLN loading
/// </summary>
bool blnLoading = false;
/// <summary>
/// Handles the Paint event of the Parent control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="PaintEventArgs"/> instance containing the event data.</param>
void Parent_Paint(object sender, PaintEventArgs e)
{
if (blnLoading)
return;
if (shadowHeight > )
{
var control = sender as Control;
var lst = m_controlCache.Where(p => p.Key.Parent == control && p.Value);
if (lst != null && lst.Count() > )
{
blnLoading = true;
e.Graphics.SetGDIHigh();
foreach (var item in lst)
{
Control _control = item.Key; using (Bitmap bit = new Bitmap(_control.Width, _control.Height))
{
_control.DrawToBitmap(bit, _control.ClientRectangle);
using (Bitmap bitNew = new Bitmap(bit.Width, (int)(bit.Height * shadowHeight)))
{
using (var g = Graphics.FromImage(bitNew))
{
g.DrawImage(bit, new RectangleF(, , bitNew.Width, bitNew.Height), new RectangleF(, bit.Height - bit.Height * shadowHeight, bit.Width, bit.Height * shadowHeight), GraphicsUnit.Pixel);
}
bitNew.RotateFlip(RotateFlipType.Rotate180FlipNone);
e.Graphics.DrawImage(bitNew, new Point(_control.Location.X, _control.Location.Y + _control.Height + ));
Color bgColor = GetParentColor(_control);
LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(_control.Location.X, _control.Location.Y + _control.Height + , bitNew.Width, bitNew.Height), Color.FromArgb(, bgColor), bgColor, 90f); //75f 表示角度
e.Graphics.FillRectangle(lgb, new Rectangle(new Point(_control.Location.X, _control.Location.Y + _control.Height + ), bitNew.Size));
}
}
}
}
}
blnLoading = false;
} /// <summary>
/// Gets the color of the parent.
/// </summary>
/// <param name="c">The c.</param>
/// <returns>Color.</returns>
private Color GetParentColor(Control c)
{
if (c.Parent.BackColor != Color.Transparent)
{
return c.Parent.BackColor;
}
return GetParentColor(c.Parent);
}
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧
(七十八)c#Winform自定义控件-倒影组件的更多相关文章
- (七十)c#Winform自定义控件-饼状图
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- (三十)c#Winform自定义控件-文本框(三)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (七十三)c#Winform自定义控件-资源加载窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- Unity3D研究院之Jenkins的使用(七十八)
长夜漫漫无心睡眠,来一篇嘿嘿.我相信如果已经用Shell脚本完成IOS和Android打包的朋友一定需要Jenkins 怎么才能让策划打包ipa和apk?怎么才能彻底省去程序的时间,只要在同一局域网内 ...
- (七十八)使用第三方框架INTULocationManager实现定位
前面(第七十五.七十六篇)讲述了如何通过CoreLocation获取位置,授权.获取等相当复杂,如果借助于第三方框架,可以简单的实现授权与定位. 首先在GitHub中搜索LocationManager ...
- (二十)c#Winform自定义控件-有后退的窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- (五十)c#Winform自定义控件-滑块
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- (八十)c#Winform自定义控件-分割线标签-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- (十)c#Winform自定义控件-横向列表
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
随机推荐
- Spring学习之旅(十三)--使用NoSQL数据库
除了关系型数据库之外,现在还有一种 NoSQL 数据库非常流行,而 Spring 自然也没有放过对它的支持. NoSQL 数据库有很多种,如: MongoDBGenericJackson2JsonRe ...
- 18_init 函数的使用
1.init()函数是一个内置函数,在程序执行前会先执行init()函数,及在main()函数执行前执行 2.如果调用包里有init()函数,会先执行调用包的init()函数,在这执行本函数的init ...
- 从SpringBoot构建十万博文聊聊限流特技
前言 在开发十万博客系统的的过程中,前面主要分享了爬虫.缓存穿透以及文章阅读量计数等等.爬虫的目的就是解决十万+问题:缓存穿透是为了保护后端数据库查询服务:计数服务解决了接近真实阅读数以及数据库服务的 ...
- C#开发BIMFACE系列13 服务端API之获取转换状态
系列目录 [已更新最新开发文章,点击查看详细] 在<C#开发BIMFACE系列12 服务端API之文件转换>中详细介绍了7种文件转换的方法.发起源文件/模型转换后,转换过程可能成功 ...
- 在.net core web api项目中安装swagger展示api接口(相当于生成api文档)
1, 建立或打开项目后,在“程序包管理器控制台”中执行以下命令添加包引用: Install-Package Swashbuckle.AspNetCore 2,在项目中打开Startup.cs文件,找 ...
- 一本通 P1486 【黑暗城堡】
题库 :一本通 题号 :1486 题目 :黑暗城堡 link :http://ybt.ssoier.cn:8088/problem_show.php?pid=1486 思路 :这道题既然要求使加入生成 ...
- Spring Boot2 系列教程(一)纯 Java 搭建 SSM 项目
在 Spring Boot 项目中,正常来说是不存在 XML 配置,这是因为 Spring Boot 不推荐使用 XML ,注意,并非不支持,Spring Boot 推荐开发者使用 Java 配置来搭 ...
- win8,右键添加notepad++
1.下载并安装notepad++ 2.创建txt文件test1.txt,内容如下: Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\ ...
- HDU2485Destroying the bus stations 拆点网络流求割点个数
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2485 题目要求:删除最少的点,使得源点到汇点的距离大于k 思路:拆点.建图求费用小于等于k的最大流 # ...
- UVA - 315 Network(tarjan求割点的个数)
题目链接:https://vjudge.net/contest/67418#problem/B 题意:给一个无向连通图,求出割点的数量.首先输入一个N(多实例,0结束),下面有不超过N行的数,每行的第 ...