2014年9月28日 星期日

C# - Bypass read only cells in DatagridView when pressing TAB (Shift+TAB) key

在 Visual Studio 裡,DataDridView 不會自動跳過唯讀欄位,在網路上找了好久才找到一、兩篇相關的文章,但是都有一些問題,最後我把它整理好,且用在自己的工作上。

下列程式碼,是用來跳過 DataGridView 中唯讀的欄位,希望對大家有幫助:

I learned it from the web: http://social.msdn.microsoft.com/Forums/windows/en-US/2025a294-9143-4ecf-82b1-f632da163e85/bypass-read-only-cells-in-datagridview-when-pressing-tab-key?forum=winforms

Note: Do not remove try {} catch {} blocks, it will bypass OnCellValiding() exception....

using System.Windows.Forms;

namespace TestDataGridView
{
    public partial class IfDataGridView : DataGridView
    {
        public IfDataGridView()
        {
            InitializeComponent();
        }

        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (null == this.CurrentCell)
            {
                return true;
            }

            Keys key = keyData & Keys.KeyCode;
            if (!(key == Keys.ShiftKey || (int)keyData == 65545)) // 沒有按著 Shift
            {
                if (key == Keys.Tab)
                {
                    try
                    {
                        DataGridViewColumn nextColumn = this.Columns.GetNextColumn(this.Columns[this.CurrentCell.ColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                        if (null != nextColumn)
                        {
                            this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[nextColumn.Index];
                        }
                        else
                        {
                            nextColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                            if ((this.CurrentCell.RowIndex + 1) == this.Rows.Count)
                            {
                                this.CurrentCell = this.Rows[0].Cells[nextColumn.Index];
                            }
                            else
                            {
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex + 1].Cells[nextColumn.Index];
                            }
                        }
                    }
                    catch {}
                    return true;
                }
            }
            else
            {
                if (key == Keys.Tab)
                {
                    try {
                        DataGridViewColumn nextColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                        DataGridViewColumn priorColumn = nextColumn;
                        //
                        if (nextColumn.DisplayIndex >= this.Columns[this.CurrentCell.ColumnIndex].DisplayIndex)
                        {
                            if (this.CurrentCell.RowIndex > 0)
                            {
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex - 1].Cells[this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly).Index];
                            }
                            else
                            {
                                this.CurrentCell = this.Rows[this.Rows.Count - 1].Cells[this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly).Index];
                            }
                        }
                        else
                        {
                            //Same Row
                            while (nextColumn.DisplayIndex < this.Columns[this.CurrentCell.ColumnIndex].DisplayIndex)
                            {
                                priorColumn = nextColumn;
                                nextColumn = this.Columns.GetNextColumn(this.Columns[nextColumn.Index], DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                            }
                            this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[priorColumn.Index];
                        }
                    }
                    catch {}
                    return true;
                }
            }

            return base.ProcessDialogKey(keyData);
        }

        protected override bool ProcessDataGridViewKey(KeyEventArgs e)
        {
            if (null == this.CurrentCell)
            {
                return true;
            }
   //
            if (!e.Shift)
            {
                if (e.KeyData == Keys.Tab)
                {
                    //
                    try
                    {
                        DataGridViewColumn nextColumn = this.Columns.GetNextColumn(this.Columns[this.CurrentCell.ColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                        if (null != nextColumn)
                        {
                            this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[nextColumn.Index];
                        }
                        else
                        {
                            nextColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                            if ((this.CurrentCell.RowIndex + 1) == this.Rows.Count)
                            {
                                this.CurrentCell = this.Rows[0].Cells[nextColumn.Index];
                            }
                            else
                            {
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex + 1].Cells[nextColumn.Index];
                            }
                        }
                    }
                    catch { }
                    return true;
                }
                //判斷編輯狀態下,游標在最左邊,還是在最右邊??
                bool isEditing = false;
                if (this.IsCurrentCellInEditMode && this.CurrentCell.EditType == typeof(DataGridViewTextBoxEditingControl))
                {
                    isEdititng = (((TextBox)this.EditingControl).SelectionStart > 0) &&
                                    (((TextBox)this.EditingControl).SelectionStart < ((TextBox)this.EditingControl).Text.Length);
                }
                if (!Edititng)
                {
                    // 按下向右鍵
                    if (e.KeyData == Keys.Right || e.KeyData == Keys.Enter)
                    {
                        try
                        {
                            DataGridViewColumn nextColumn = this.Columns.GetNextColumn(this.Columns[this.CurrentCell.ColumnIndex], DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                            if (null != nextColumn)
                            {
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[nextColumn.Index];
                            }
                            else
                            {
                                nextColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[nextColumn.Index];
                            }
                        }
                        catch { }
                        return true;
                    }
                    // 按下向左鍵
                    if (e.KeyData == Keys.Left)
                    {
                        try
                        {
                            DataGridViewColumn nextColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                            DataGridViewColumn priorColumn = nextColumn;

                            if (nextColumn.DisplayIndex >= this.Columns[this.CurrentCell.ColumnIndex].DisplayIndex)
                            {
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly).Index];
                            }
                            else
                            {
                                //Same Row
                                while (nextColumn.DisplayIndex < this.Columns[this.CurrentCell.ColumnIndex].DisplayIndex)
                                {
                                    priorColumn = nextColumn;
                                    nextColumn = this.Columns.GetNextColumn(this.Columns[nextColumn.Index], DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                                }
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[priorColumn.Index];
                            }
                        }
                        catch { }
                        return true;
                    }
                }
                // 按向上鍵
                if (e.KeyData == Keys.Up)
                {
                    try
                    {
                        if (this.CurrentCell.RowIndex > 0)
                        {
                            this.CurrentCell = this.Rows[this.CurrentCell.RowIndex - 1].Cells[this.CurrentCell.ColumnIndex];
                        }
                        else
                        {
                            this.CurrentCell = this.Rows[this.Rows.Count - 1].Cells[this.CurrentCell.ColumnIndex];
                        }
                    }
                    catch { }
                    return true;
                }
                // 按向下鍵
                if (e.KeyData == Keys.Down)
                {
                    try
                    {
                        if ((this.CurrentCell.RowIndex + 1) == this.Rows.Count)
                        {
                            this.CurrentCell = this.Rows[0].Cells[this.CurrentCell.ColumnIndex];
                        }
                        else
                        {
                            this.CurrentCell = this.Rows[this.CurrentCell.RowIndex + 1].Cells[this.CurrentCell.ColumnIndex];
                        }
                    }
                    catch { }
                    return true;
                }
            }
            //
            if (e.Shift || (int)e.KeyData == 65545)
            {
                if ((e.KeyData & Keys.Tab) == Keys.Tab)
                {
                    try
                    {
                        DataGridViewColumn nextColumn = this.Columns.GetFirstColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                        DataGridViewColumn priorColumn = nextColumn;
                        //
                        if (nextColumn.DisplayIndex >= this.Columns[this.CurrentCell.ColumnIndex].DisplayIndex)
                        {
                            if (this.CurrentCell.RowIndex > 0)
                            {
                                this.CurrentCell = this.Rows[this.CurrentCell.RowIndex - 1].Cells[this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly).Index];
                            }
                            else
                            {
                                this.CurrentCell = this.Rows[this.Rows.Count - 1].Cells[this.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly).Index];
                            }
                        }
                        else
                        {
                            //Same Row
                            while (nextColumn.DisplayIndex < this.Columns[this.CurrentCell.ColumnIndex].DisplayIndex)
                            {
                                priorColumn = nextColumn;
                                nextColumn = this.Columns.GetNextColumn(this.Columns[nextColumn.Index], DataGridViewElementStates.Visible, DataGridViewElementStates.ReadOnly);
                            }
                            this.CurrentCell = this.Rows[this.CurrentCell.RowIndex].Cells[priorColumn.Index];
                        }
                    }
                    catch { }
                    return true;
                }
            }
            return base.ProcessDataGridViewKey(e);
        }
    }
}

沒有留言:

張貼留言