(七十八)c#Winform自定义控件-倒影组件
程序员文章站
2024-02-08 19:53:34
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_contr ......
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
github:https://github.com/kwwwvagaa/netwinformcontrol
码云:
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
来都来了,点个【推荐】再走吧,谢谢
nuget
install-package hzh_controls
目录
用处及效果
准备工作
gdi+画图,不了解先百度
开始
思路:
控件扩展属性,在组件中对需要显示倒影的控件的父控件添加paint事件,在paint事件中绘制控件,并旋转180,然后画到父控件上,然后再覆盖一层渐变色,完美。
添加一个类shadowcomponent 继承component,实现 iextenderprovider接口,扩展属性
代码比较少,直接放上来了
1 /// <summary> 2 /// the m control cache 3 /// </summary> 4 dictionary<control, bool> m_controlcache = new dictionary<control, bool>(); 5 6 #region 构造函数 english:constructor 7 /// <summary> 8 /// initializes a new instance of the <see cref="shadowcomponent" /> class. 9 /// </summary> 10 public shadowcomponent() 11 { 12 13 } 14 15 /// <summary> 16 /// initializes a new instance of the <see cref="shadowcomponent" /> class. 17 /// </summary> 18 /// <param name="container">the container.</param> 19 public shadowcomponent(icontainer container) 20 : this() 21 { 22 container.add(this); 23 } 24 #endregion 25 26 /// <summary> 27 /// 指定此对象是否可以将其扩展程序属性提供给指定的对象。 28 /// </summary> 29 /// <param name="extendee">要接收扩展程序属性的 <see cref="t:system.object" />。</param> 30 /// <returns>如果此对象可以扩展程序属性提供给指定对象,则为 true;否则为 false。</returns> 31 public bool canextend(object extendee) 32 { 33 if (extendee is control && !(extendee is form)) 34 return true; 35 return false; 36 } 37 38 /// <summary> 39 /// gets the show shadow. 40 /// </summary> 41 /// <param name="control">the control.</param> 42 /// <returns><c>true</c> if xxxx, <c>false</c> otherwise.</returns> 43 [browsable(true), category("自定义属性"), description("是否显示倒影"), displayname("showshadow"), localizable(true)] 44 public bool getshowshadow(control control) 45 { 46 if (m_controlcache.containskey(control)) 47 return m_controlcache[control]; 48 else 49 return false; 50 } 51 52 /// <summary> 53 /// sets the show shadow. 54 /// </summary> 55 /// <param name="control">the control.</param> 56 /// <param name="isshowshadow">if set to <c>true</c> [is show shadow].</param> 57 public void setshowshadow(control control, bool isshowshadow) 58 { 59 control.parentchanged += control_parentchanged; 60 m_controlcache[control] = isshowshadow; 61 } 62 63 /// <summary> 64 /// handles the parentchanged event of the control control. 65 /// </summary> 66 /// <param name="sender">the source of the event.</param> 67 /// <param name="e">the <see cref="eventargs"/> instance containing the event data.</param> 68 void control_parentchanged(object sender, eventargs e) 69 { 70 control control = sender as control; 71 if (control.parent != null && m_controlcache[control]) 72 { 73 if (!lstpainteventcontrol.contains(control.parent)) 74 { 75 lstpainteventcontrol.add(control.parent); 76 type type = control.parent.gettype(); 77 system.reflection.propertyinfo pi = type.getproperty("doublebuffered", system.reflection.bindingflags.instance | system.reflection.bindingflags.nonpublic); 78 pi.setvalue(control.parent, true, null); 79 control.parent.paint += parent_paint; 80 } 81 } 82 } 83 84 /// <summary> 85 /// the lst paint event control 86 /// </summary> 87 list<control> lstpainteventcontrol = new list<control>(); 88 /// <summary> 89 /// the shadow height 90 /// </summary> 91 private float shadowheight = 0.3f; 92 93 /// <summary> 94 /// gets or sets the height of the shadow. 95 /// </summary> 96 /// <value>the height of the shadow.</value> 97 [browsable(true), category("自定义属性"), description("倒影高度,0-1"), localizable(true)] 98 public float shadowheight 99 { 100 get { return shadowheight; } 101 set { shadowheight = value; } 102 } 103 /// <summary> 104 /// the bln loading 105 /// </summary> 106 bool blnloading = false; 107 /// <summary> 108 /// handles the paint event of the parent control. 109 /// </summary> 110 /// <param name="sender">the source of the event.</param> 111 /// <param name="e">the <see cref="painteventargs"/> instance containing the event data.</param> 112 void parent_paint(object sender, painteventargs e) 113 { 114 if (blnloading) 115 return; 116 if (shadowheight > 0) 117 { 118 var control = sender as control; 119 var lst = m_controlcache.where(p => p.key.parent == control && p.value); 120 if (lst != null && lst.count() > 0) 121 { 122 blnloading = true; 123 e.graphics.setgdihigh(); 124 foreach (var item in lst) 125 { 126 control _control = item.key; 127 128 using (bitmap bit = new bitmap(_control.width, _control.height)) 129 { 130 _control.drawtobitmap(bit, _control.clientrectangle); 131 using (bitmap bitnew = new bitmap(bit.width, (int)(bit.height * shadowheight))) 132 { 133 using (var g = graphics.fromimage(bitnew)) 134 { 135 g.drawimage(bit, new rectanglef(0, 0, bitnew.width, bitnew.height), new rectanglef(0, bit.height - bit.height * shadowheight, bit.width, bit.height * shadowheight), graphicsunit.pixel); 136 } 137 bitnew.rotateflip(rotatefliptype.rotate180flipnone); 138 e.graphics.drawimage(bitnew, new point(_control.location.x, _control.location.y + _control.height + 1)); 139 color bgcolor = getparentcolor(_control); 140 lineargradientbrush lgb = new lineargradientbrush(new rectangle(_control.location.x, _control.location.y + _control.height + 1, bitnew.width, bitnew.height), color.fromargb(50, bgcolor), bgcolor, 90f); //75f 表示角度 141 e.graphics.fillrectangle(lgb, new rectangle(new point(_control.location.x, _control.location.y + _control.height + 1), bitnew.size)); 142 } 143 } 144 } 145 } 146 } 147 blnloading = false; 148 } 149 150 /// <summary> 151 /// gets the color of the parent. 152 /// </summary> 153 /// <param name="c">the c.</param> 154 /// <returns>color.</returns> 155 private color getparentcolor(control c) 156 { 157 if (c.parent.backcolor != color.transparent) 158 { 159 return c.parent.backcolor; 160 } 161 return getparentcolor(c.parent); 162 }
最后的话
如果你喜欢的话,请到 点个星星吧
上一篇: 奥飞动漫推三款机器人并参股图灵
下一篇: iOS实现毫秒倒计时的方法详解