欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

(七十八)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

目录

用处及效果

(七十八)c#Winform自定义控件-倒影组件

准备工作

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         }

 

最后的话

如果你喜欢的话,请到  点个星星吧