using System.Windows.Media; namespace System.Windows.Forms { public class ShadowControl : Control { private Shadow shadow { get; } private System.Drawing.Color color; public Drawing.Color Color { get => color; set { color = value; UpdateControl(); } } private int depth; public int Depth { get => depth; set { depth = value; UpdateControl(); } } private DockStyle dock; public override DockStyle Dock { get => dock; set { dock = value; UpdateControl(); } } private void UpdateControl() { int angle = dock switch { DockStyle.Left => 180, DockStyle.Bottom => 90, DockStyle.Top => 270, _ => 0, }; bool vertical = dock == DockStyle.Left || dock == DockStyle.Right; if (vertical) shadow.Width = depth; else shadow.Height = depth; shadow.Background = new LinearGradientBrush(Helper.GetColor(Color), Helper.GetColor(System.Drawing.Color.FromArgb(0, Color)), angle); shadow.InvalidateVisual(); } public ShadowControl() { shadow = new Shadow() { IsHitTestVisible = false }; SetControl(shadow); depth = 3; Dock = DockStyle.Bottom; } private class Shadow : System.Windows.Controls.Control { protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); drawingContext.PushOpacity(0.7); drawingContext.DrawRectangle(Background, null, new Rect(0, 0, ActualWidth, ActualHeight)); } } } public static class ShadowControlExtensions { public static ShadowControl SetShadow(this Control control, DockStyle dock) { var shadow = new ShadowControl() { Dock = dock }; var shCtl = shadow.control; var ctl = control.control; (ctl.Parent as System.Windows.Controls.Panel)?.Children.Add(shadow.control); ctl.LayoutUpdated += (s, e) => { shCtl.Visibility = ctl.Visibility; switch (shadow.Dock) { case DockStyle.Left: shCtl.Margin = new Thickness(ctl.Margin.Left - shadow.Depth, ctl.Margin.Top, 0, 0); shCtl.Height = ctl.ActualHeight; break; case DockStyle.Right: shCtl.Margin = new Thickness(ctl.Margin.Left + ctl.ActualWidth, ctl.Margin.Top, 0, 0); shCtl.Height = ctl.ActualHeight; break; case DockStyle.Top: shCtl.Margin = new Thickness(ctl.Margin.Left, ctl.Margin.Top - shadow.Depth, 0, 0); shCtl.Width = ctl.ActualWidth; break; case DockStyle.Bottom: shCtl.Margin = new Thickness(ctl.Margin.Left, ctl.Margin.Top + ctl.ActualHeight, 0, 0); shCtl.Width = ctl.ActualWidth; break; } }; return shadow; } } }