namespace System.Windows.Forms { public class Splitter : Control { private Control indicator; private System.Drawing.Point mouseDownPoint; public override DockStyle Dock { get => base.Dock; set { base.Dock = value; Cursor = value == DockStyle.Left || value == DockStyle.Right ? Cursors.VSplit : Cursors.HSplit; if (value == DockStyle.Left || value == DockStyle.Right) Width = 3; else Height = 3; } } public int MinSize { get; set; } // TODO: check public int MinExtra { get; set; } // TODO? public event SplitterEventHandler SplitterMoved; private Control GetResizableControl() { for (int i = Parent.Controls.Count - 1; i >= 0; i--) { var c = Parent.Controls[i]; if (c != this && c.Dock == this.Dock) return c; } return null; } protected virtual void OnSplitterMoved(SplitterEventArgs e) => SplitterMoved?.Invoke(this, e); protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (GetResizableControl() == null) return; mouseDownPoint = e.Location; indicator = new Control(); indicator.BackColor = System.Drawing.Color.Black; indicator.Parent = this.Parent; indicator.Location = this.Location; indicator.Size = this.Size; indicator.BringToFront(); } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.Button == MouseButtons.Left) { if (indicator == null) return; if (Dock == DockStyle.Left || Dock == DockStyle.Right) { int x = Left + e.X - mouseDownPoint.X; if (x >= 0 && x < Parent.Width - Width && x >= MinSize) indicator.Left = x; } else { int y = Top + e.Y - mouseDownPoint.Y; if (y >= 0 && y < Parent.Height - Height && y >= MinSize) indicator.Top = y; } } } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (indicator == null) return; Control resizableControl = GetResizableControl(); if (resizableControl == null) return; if (Dock == DockStyle.Left) resizableControl.Width -= Left - indicator.Left; else if (Dock == DockStyle.Right) resizableControl.Width += Left - indicator.Left; else if (Dock == DockStyle.Top) resizableControl.Height -= Top - indicator.Top; else if (Dock == DockStyle.Bottom) resizableControl.Height += Top - indicator.Top; indicator.Dispose(); // TODO: check arguments OnSplitterMoved(new SplitterEventArgs(0, 0, resizableControl.Width, resizableControl.Height)); } public Splitter() { Dock = DockStyle.Left; } } }