ListViewEx – Auto resize selected column

What do you do when you get fed up having to write the same code over and over again? Write a base class for it… of course.

I regularly use the WinForms ListView control and often want to specify a specific column (in detail view) that must auto resize when the whole control resize. Therefore I created the following class that does all that (and more stuff) to make life easier.

public class ListViewEx : ListView
    {
        public ListViewEx()
            : base()
        {
            DoubleBuffered = true;
            View = View.Details;
            resizeTimer.Tick +=  resizeTimer_Tick;
        }

        [Description("Use one column to auto resize in detail view")]
        public bool AutoResizeColumnEnabled { get; set; }
        [Description("Column index of auto resize column")]
        public int AutoResizeColumnIndex { get; set; }
        public event MethodInvoker EnterKeyPressed;
        public event MethodInvoker DeleteKeyPressed;
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
                if (EnterKeyPressed != null)
                {
                    EnterKeyPressed();
                    e.Handled = true;
                }
            base.OnKeyPress(e);
        }
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
                if (DeleteKeyPressed != null)
                {
                    DeleteKeyPressed();
                    e.Handled = true;
                }
            base.OnKeyDown(e);
        }
        private Timer resizeTimer = new Timer() { Interval = 100, Enabled = false };
        private void resizeTimer_Tick(object sender, EventArgs e)
        {
            resizeTimer.Enabled = false;
            try
            {
                if (AutoResizeColumnEnabled && View == System.Windows.Forms.View.Details &&
                    AutoResizeColumnIndex > -1 && this.Columns.Count > AutoResizeColumnIndex)
                {
                    int columnsWidth = 0;
                    Application.DoEvents();
                    for (int i = 0; i < this.Columns.Count; i++)
                    {
                        if (i != AutoResizeColumnIndex)
                            columnsWidth += this.Columns[i].Width;
                    }
                    this.Columns[AutoResizeColumnIndex].Width = this.ClientSize.Width - columnsWidth - 2;
                }
            }
            catch { }
        }
        protected override void OnResize(EventArgs e)
        {
            resizeTimer.Enabled = false;
            resizeTimer.Enabled = true;
            base.OnResize(e);
        }
    }

Now all you have to do is set the AutoResizeColumnEnabled property to true and specify a column index for AutoResizeColumnIndex and there you go. Easy hey?

Leave a Reply

%d bloggers like this: