// *********************************************************************** // Assembly : HZH_Controls // Created : 2019-09-28 // // *********************************************************************** // // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com // // // Blog: https://www.cnblogs.com/bfyx // GitHub:https://github.com/kwwwvagaa/NetWinformControl // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git // // If you use this code, please keep this note. // *********************************************************************** using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Windows.Forms; using System.ComponentModel; using System.Drawing.Drawing2D; namespace HZH_Controls.Controls { /// /// Class ShadowComponent. /// Implements the /// Implements the /// /// /// [ProvideProperty("ShowShadow", typeof(Control))] public class ShadowComponent : Component, IExtenderProvider { /// /// The m control cache /// Dictionary m_controlCache = new Dictionary(); #region 构造函数 English:Constructor /// /// Initializes a new instance of the class. /// public ShadowComponent() { } /// /// Initializes a new instance of the class. /// /// The container. public ShadowComponent(IContainer container) : this() { container.Add(this); } #endregion /// /// 指定此对象是否可以将其扩展程序属性提供给指定的对象。 /// /// 要接收扩展程序属性的 。 /// 如果此对象可以扩展程序属性提供给指定对象,则为 true;否则为 false。 public bool CanExtend(object extendee) { if (extendee is Control && !(extendee is Form)) return true; return false; } /// /// Gets the show shadow. /// /// The control. /// true if XXXX, false otherwise. [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; } /// /// Sets the show shadow. /// /// The control. /// if set to true [is show shadow]. public void SetShowShadow(Control control, bool isShowShadow) { control.ParentChanged += control_ParentChanged; m_controlCache[control] = isShowShadow; } /// /// Handles the ParentChanged event of the control control. /// /// The source of the event. /// The instance containing the event data. 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; } } } /// /// The LST paint event control /// List lstPaintEventControl = new List(); /// /// The shadow height /// private float shadowHeight = 0.3f; /// /// Gets or sets the height of the shadow. /// /// The height of the shadow. [Browsable(true), Category("自定义属性"), Description("倒影高度,0-1"), Localizable(true)] public float ShadowHeight { get { return shadowHeight; } set { shadowHeight = value; } } /// /// The BLN loading /// bool blnLoading = false; /// /// Handles the Paint event of the Parent control. /// /// The source of the event. /// The instance containing the event data. void Parent_Paint(object sender, PaintEventArgs e) { if (blnLoading) return; if (shadowHeight > 0) { var control = sender as Control; var lst = m_controlCache.Where(p => p.Key.Parent == control && p.Value); if (lst != null && lst.Count() > 0) { 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(0, 0, bitNew.Width, bitNew.Height), new RectangleF(0, bit.Height - bit.Height * shadowHeight, bit.Width, bit.Height * shadowHeight), GraphicsUnit.Pixel); } bitNew.RotateFlip(RotateFlipType.RotateNoneFlipY); e.Graphics.DrawImage(bitNew, new Point(_control.Location.X, _control.Location.Y + _control.Height + 1)); Color bgColor = GetParentColor(_control); 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 表示角度 e.Graphics.FillRectangle(lgb, new Rectangle(new Point(_control.Location.X, _control.Location.Y + _control.Height + 1), bitNew.Size)); } } } } } blnLoading = false; } /// /// Gets the color of the parent. /// /// The c. /// Color. private Color GetParentColor(Control c) { if (c.Parent.BackColor != Color.Transparent) { return c.Parent.BackColor; } return GetParentColor(c.Parent); } } }