Friday, December 13, 2024

C# Create Editable ListView

 Note: Calculate the position of click allowing for location of scroll bar, then use the textbox or combobox hide the previous cell and accept the input and then write back to cell.


using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Infor.SyteLine.ClrProc
{
    /// <summary>
    /// Summary description for SMK_EditListView.
    /// </summary>
    public class SMK_EditListView : ListView
    {
        private ListViewItem li;
        private int trackHScrollPosition = 0;
        private int X = 0;
        private int Y = 0;
        private string subItemText;
        private int subItemSelected = 0;
        private System.Windows.Forms.TextBox editBox = new System.Windows.Forms.TextBox();
        private System.Windows.Forms.ComboBox cmbBox = new System.Windows.Forms.ComboBox();

        public SMK_EditListView()
        {
            cmbBox.Items.Add("Functions");
            cmbBox.Items.Add("StoredProcedures");

            cmbBox.Size = new System.Drawing.Size(0, 0);
            cmbBox.Location = new System.Drawing.Point(0, 0);
            this.Controls.AddRange(new System.Windows.Forms.Control[] { this.cmbBox });
            cmbBox.SelectedIndexChanged += new System.EventHandler(this.CmbSelected);
            cmbBox.LostFocus += new System.EventHandler(this.CmbFocusOver);
            cmbBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.CmbKeyPress);
            cmbBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            cmbBox.BackColor = Color.SkyBlue;
            cmbBox.DropDownStyle = ComboBoxStyle.DropDownList;
            cmbBox.Hide();

            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            this.FullRowSelect = true;
            this.Name = "listView1";
            this.Size = new System.Drawing.Size(0, 0);
            this.TabIndex = 0;
            this.View = System.Windows.Forms.View.Details;
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.SMKMouseDown);
            this.DoubleClick += new System.EventHandler(this.SMKDoubleClick);
            this.GridLines = true;

            editBox.Size = new System.Drawing.Size(0, 0);
            editBox.Location = new System.Drawing.Point(0, 0);
            this.Controls.AddRange(new System.Windows.Forms.Control[] { this.editBox });
            editBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.EditOver);
            editBox.LostFocus += new System.EventHandler(this.FocusOver);
            editBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            editBox.BackColor = Color.LightYellow;
            editBox.BorderStyle = BorderStyle.Fixed3D;
            editBox.Hide();
            editBox.Text = "";
        }

        private void CmbKeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (e.KeyChar == 13 || e.KeyChar == 27)
            {
                cmbBox.Hide();
            }
        }

        private void CmbSelected(object sender, System.EventArgs e)
        {
            int sel = cmbBox.SelectedIndex;
            if (sel >= 0)
            {
                string itemSel = cmbBox.Items[sel].ToString();
                li.SubItems[subItemSelected].Text = itemSel;
            }
        }

        private void CmbFocusOver(object sender, System.EventArgs e)
        {
            cmbBox.Hide();
        }

        private void EditOver(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                li.SubItems[subItemSelected].Text = editBox.Text;
                editBox.Hide();
            }

            if (e.KeyChar == 27)
                editBox.Hide();
        }

        private void FocusOver(object sender, System.EventArgs e)
        {
            li.SubItems[subItemSelected].Text = editBox.Text;
            editBox.Hide();
        }

        public void SMKDoubleClick(object sender, System.EventArgs e)
        {
            ScrollInfoStruct si = GetScrollInfoStruct(SBS_HORZ);

            // Check the subitem clicked .
            int nStart = X + si.nPos;
            int spos = 0;
            int epos = 0; 
            for (int i = 0; i < this.Columns.Count; i++)
            {
                spos = epos;
                epos += this.Columns[i].Width;

                if (nStart > spos && nStart < epos)
                {
                    subItemSelected = i;
                    break;
                }

            }          

            Console.WriteLine("SUB ITEM SELECTED = " + li.SubItems[subItemSelected].Text);
            subItemText = li.SubItems[subItemSelected].Text;

            string colName = this.Columns[subItemSelected].Text;
            if (colName == "File" || colName == "Name")
            {
                editBox.Size = new System.Drawing.Size(epos - spos, li.Bounds.Bottom - li.Bounds.Top);
                editBox.Location = new System.Drawing.Point(spos - si.nPos, li.Bounds.Y);
                editBox.Show();
                editBox.Text = subItemText;
                editBox.SelectAll();
                editBox.Focus();
            }
            else
            {
                cmbBox.Size = new System.Drawing.Size(epos - spos, li.Bounds.Bottom - li.Bounds.Top); 
                cmbBox.Location = new System.Drawing.Point(spos - si.nPos, li.Bounds.Y);
                cmbBox.Show();
                cmbBox.Text = subItemText;
                cmbBox.SelectAll();
                cmbBox.Focus();
            }
        }

        private ScrollInfoStruct GetScrollInfoStruct(int direction)
        {
            ScrollInfoStruct si = new ScrollInfoStruct();
            si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
            si.cbSize = Marshal.SizeOf(si);
            GetScrollInfo(this.Handle, direction, ref si);
            return si;
        }

        public void SMKMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            li = this.GetItemAt(e.X, e.Y);
            X = e.X;
            Y = e.Y;
        }
        
        protected void OnScroll()
        {
            ScrollInfoStruct si = GetScrollInfoStruct(SBS_HORZ);

            editBox.Location = new System.Drawing.Point(editBox.Location.X - (si.nPos - trackHScrollPosition), editBox.Location.Y);
            cmbBox.Location = new System.Drawing.Point(cmbBox.Location.X - (si.nPos - trackHScrollPosition), cmbBox.Location.Y);
            trackHScrollPosition = si.nPos;
        }

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == WM_HSCROLL || m.Msg == WM_VSCROLL)
            { 
                this.OnScroll(); 
            }
        }

        #region DLL IMPORT
        [DllImport("user32")]
        static extern IntPtr SendMessage(IntPtr Handle, Int32 msg, IntPtr
        wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetScrollInfo(IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo);

        [DllImport("user32.dll")]
        static extern int SetScrollInfo(IntPtr hwnd, int fnBar, ref ScrollInfoStruct lpsi, bool fRedraw);

        private struct ScrollInfoStruct
        {
            public int cbSize;
            public int fMask;
            public int nMin;
            public int nMax;
            public int nPage;
            public int nPos;
            public int nTrackPos;
        }

        const int SB_LINELEFT = 0;
        const int SB_LINERIGHT = 1;
        const int SB_PAGELEFT = 2; //same value as SB_PAGEUP
        const int SB_PAGERIGHT = 3; //same value as SB_PAGEDOWN
        const int SB_THUMBPOSITION = 4;
        const int SB_THUMBTRACK = 5;
        const int SB_LEFT = 6;
        const int SB_RIGHT = 7;
        const int SB_ENDSCROLL = 8;
        const int WM_HSCROLL = 0x0114;
        const int WM_VSCROLL = 0x115;

        const int SBS_HORZ = 0;
        const int SBS_VERT = 1;

        private const int SIF_RANGE = 0x1;
        private const int SIF_PAGE = 0x2;
        private const int SIF_POS = 0x4;
        private const int SIF_TRACKPOS = 0x10;
        private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS |
        SIF_TRACKPOS;

        #endregion
    }
}

No comments:

Post a Comment