Focus sending Control

Nusrat Bharucha 100 Reputation points
2023-11-15T19:13:13.8233333+00:00

Hi ,

i asked a question here at https://learn.microsoft.com/en-us/answers/questions/1389642/change-datagridview-keys which was answered by @KOZ6.0 . I applied his solution with some modifications as per my requirement . Below is the code

    protected override void OnEnter(EventArgs e)
        { 
             if (RowCount == 0)
            {
                TryAddRow();
                this.CurrentCell = this.Rows[0].Cells[0];
            }
            base.OnEnter(e);
        }       

       
        protected override void OnCellEnter(DataGridViewCellEventArgs e)
        {
            DataGridViewColumn column = Columns[e.ColumnIndex];
            if (!column.ReadOnly && column is DataGridViewTextBoxColumn)
            {
                BeginEdit(false); // false means don't select 
            }
            base.OnCellEnter(e);
        }
        
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
           int  currentrowposition = CurrentCell.RowIndex;
            if (keyData == Keys.Enter || keyData == Keys.Right)
            {               
                var current = CurrentCell;
                if (current != null)
                {
                    if (IsCurrentCellDirty) 
                    {
                        CommitEdit(DataGridViewDataErrorContexts.Commit);
                        EndEdit(DataGridViewDataErrorContexts.Commit);
                    }
                    if (IsCurrentCellInEditMode)
                    {
                        EndEdit(DataGridViewDataErrorContexts.Commit);
                    }
                    int row = current.RowIndex;
                    int col = current.ColumnIndex;
                    if (row == LastRowIndex)
                    {
                        if (col == FirstVisibleColumn.Index)
                        {
                            if (Rows[row].IsNewRow || string.IsNullOrEmpty(CurrentCell.Value?.ToString()) || CurrentCell.Value.ToString() == "End of list")
                            {
                    this.Rows.RemoveAt(currentrowposition);// remove the last committed row  
                  this.CurrentCell = null; // deselect the current cell 
                                return GotoNextControl();
                            }
                        }
                    }
                    if (col == LastVisibleColumn.Index) 
                    {
                        if (TryAddRow())
                        {
                            CurrentCell = this[FirstVisibleColumn.Index, RowCount - 1];
                            return true;
                        }

                    }
                }
                return ProcessTabKey(Keys.Tab);          
        
            }           
            return base.ProcessCmdKey(ref msg, keyData); 
  
        }   

       
        protected bool TryAddRow()
        {
            try
            {
                EndEdit();
                Rows.Add();
                return true;
            }
            catch (Exception ex)
            {                
                return false;
            }
        }

        


        protected int LastRowIndex
        {
            get
            {
                return Rows.GetLastRow(DataGridViewElementStates.Visible);
            }
        }

       
        protected DataGridViewColumn FirstVisibleColumn
        {
            get
            {
                return Columns.GetFirstColumn(
                    DataGridViewElementStates.Visible,
                    DataGridViewElementStates.None);
            }
        }
     
        protected DataGridViewColumn LastVisibleColumn
        {
            get
            {
                return Columns.GetLastColumn(
                    DataGridViewElementStates.Visible,
                    DataGridViewElementStates.None);
            }
        }
       
        protected bool GotoNextControl()
        {
            inGotoNextControl = true;
            bool result = Parent.SelectNextControl(this, true, true, true, true);
            inGotoNextControl = false;
            return result;
        }
        


Now as per the above code when the value of column0 is left blank and the user presses enter , it goes to next control in tab order which is a textbox . Now here the situation , i have total two textboxes besides a datagridview on this form .

textbox1 : taborder 0

datagridview : taborder1

textbox2 : taborder 2

so when the user is at the textbox 1 having taborder0 and presses tab , he goes to datagridview having taborder1 and when he's done , he goes to textbox2 having taborder2 .

The problem is when the user is at textbox2 and if he presses shift+tab to go back to previous control which is datagridview and there is any row present in datagridview it always goes to first cell due to

   protected override void OnEnter(EventArgs e)  
      {  
            if (RowCount == 0)  
          {        
        TryAddRow();  
              this.CurrentCell = this.Rows[0].Cells[0];    
        }    
        base.OnEnter(e);   
     }  

i want that if there are some rows present in the datagridview , the selected cell should be the last row's first cell (not the first row's first cell)

but if somehow that was solved , there's a problem again . suppose there is already some rows in datagridview and instaed of textbox2 , the user is at textbox1 and presses tab , the user would go to last row's first cell . so suggest a code block which has be introduced in order to check for that

 protected override void OnEnter(EventArgs e) {
        if (!inGotoNextControl) {
            if (RowCount == 0) {
                TryAddRow();
            }
            if (RowCount > 0 && ColumnCount > 0) {

// what to add and how to know which textbox send me 
Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,735 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
9,468 questions
0 comments No comments
{count} votes

Accepted answer
  1. KOZ6.0 4,170 Reputation points
    2023-11-16T05:32:19.52+00:00

    Just check if the tab key and shift key are pressed

        private const int
            VK_TAB = 0x09,
            VK_SHIFT = 0x10;
    
        private const short
            KEY_PRESSED = 0x80;
    
        [DllImport("USER32.dll")]
        private static extern short GetKeyState(int nVirtKey);
    
        private static bool IsKeyPressed(int nVirtKey) {
            return (GetKeyState(nVirtKey) & KEY_PRESSED) == KEY_PRESSED;
        }
    
        protected override void OnEnter(EventArgs e) {
            if (RowCount == 0) {
                TryAddRow();
            }
            if (!inGotoNextControl) {
                if (FirstRowIndex >= 0 && FirstColumnIndex >= 0) {
                    bool tab = IsKeyPressed(VK_TAB);
                    bool shift = IsKeyPressed(VK_SHIFT);
                    if ((tab && !shift) || CurrentCell == null) {
                        BeginInvoke((Action)(() => {
                            CurrentCell = Rows[FirstRowIndex].Cells[FirstColumnIndex];
                        }));
                    }
                    else if (tab && shift) {
                        BeginInvoke((Action)(() => {
                            CurrentCell = Rows[LastRowIndex].Cells[FirstColumnIndex];
                        }));
                    }
                }
            }
            base.OnEnter(e);
        }
    
        protected int FirstColumnIndex {
            get {
                if (FirstVisibleColumn != null) {
                    return FirstVisibleColumn.Index;
                }
                return -1;
            }
        }
    
        protected DataGridViewColumn FirstVisibleColumn {
            get {
                return Columns.GetFirstColumn(
                    DataGridViewElementStates.Visible,
                    DataGridViewElementStates.None);
            }
        }
    
        protected int FirstRowIndex {
            get {
                return Rows.GetFirstRow(DataGridViewElementStates.Visible);
            }
        }
    
        protected int LastRowIndex {
            get {
                return Rows.GetLastRow(DataGridViewElementStates.Visible);
            }
        }
    
    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful