public enum SortOrder { Ascending, Descending, None } public delegate void SortOrderEventHandler(object sender, SortOrderEventArgs e); public partial class ColumnHeader : UserControl { public event SortOrderEventHandler SortOrderChanged; private const int SORT_ARROW_TOP = 5; private const int SORT_ARROW_MARGIN = 5; private const int SORT_ARROW_SIZE = 12; private SortOrder SortBy = SortOrder.None; private string _Caption = "label1"; public string Caption { get { return _Caption; } set { _Caption = value; lblCaption.Text = _Caption; this.Invalidate(); } } public ColumnHeader() { InitializeComponent(); } private void _ColumnHeader_Paint(object sender, PaintEventArgs e) { // Pens and Brushes Pen penGrey = new Pen(System.Drawing.Color.Gray); Pen penDarkGray = new Pen(System.Drawing.Color.DarkGray); Pen penWhite = new Pen(System.Drawing.Color.White); SolidBrush myBrush = new SolidBrush(Color.DarkGray); // Verticle lines on right edge e.Graphics.DrawLine(penGrey, this.Width - 2, 2, this.Width - 2, this.Height - 2); e.Graphics.DrawLine(penWhite, this.Width - 1, 2, this.Width - 1, this.Height - 2); // Sort order indicator int iLeft = this.Width - SORT_ARROW_SIZE - 5; Point[] points = new Point[3]; switch (SortBy) { case SortOrder.Ascending: points[0] = new Point(iLeft, SORT_ARROW_TOP); points[1] = new Point(iLeft - 5, SORT_ARROW_SIZE); points[2] = new Point(iLeft + 5, SORT_ARROW_SIZE); break; case SortOrder.Descending: points[0] = new Point(iLeft - 5, SORT_ARROW_TOP); points[1] = new Point(iLeft + 5, SORT_ARROW_TOP); points[2] = new Point(iLeft, SORT_ARROW_SIZE); break; } if (SortBy != SortOrder.None) { e.Graphics.DrawPolygon(penDarkGray, points); e.Graphics.FillPolygon(myBrush, points); } penGrey.Dispose(); penDarkGray.Dispose(); penWhite.Dispose(); } private void _ColumnHeader_Resize(object sender, EventArgs e) { this.Invalidate(); } private void _ColumnHeader_Click(object sender, EventArgs e) { _SetSortOrder(); } private void _SetSortOrder() { switch (SortBy) { case SortOrder.None: SortBy = SortOrder.Descending; break; case SortOrder.Descending: SortBy = SortOrder.Ascending; break; case SortOrder.Ascending: SortBy = SortOrder.None; break; } this.Invalidate(); OnSortOrderChanged(new SortOrderEventArgs(SortBy)); } protected virtual void OnSortOrderChanged(SortOrderEventArgs e) { SortOrderChanged(this, e); } } public class SortOrderEventArgs : EventArgs { private SortOrder _SortOrder = SortOrder.None; public SortOrder SortOrder { get { return _SortOrder; } } public SortOrderEventArgs(SortOrder NewOrder) { _SortOrder = NewOrder; } }