none
Winform textbox lost focus automatically when typing "0" but is fine for other chars RRS feed

  • Question

  • Hi guys, 

    These days I am having an interesting observation.  When I typing "0" in a textbox added to a datagridview.controls, the textbox will lose focus automatically and the focus was shifted to the datagridview's first cell.  I am curious why "0" is special.

    Codes I am using are as below. I would like to right click the datagridview column header and the textbox appear at the header position. Then it is fine to typing a to z and 1-9. But when typing "0", the first cell of the datagridview get foucs. Remember to add DgvTotal.Controls.Add(txtSearchBox) in form_load.         

    Private Sub dgvTotal_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgvTotal.ColumnHeaderMouseClick        
       Try            
           If e.Button = Windows.Forms.MouseButtons.Right Then 
                    txtSearchBox.Select()
                    txtSearchBox.Focus()                
                    txtSearchBox.Tag = e.ColumnIndex               
                    txtSearchBox.Location=dgvTotal.GetCellDisplayRectangle(e.ColumnIndex, -1, False).Location                
                    txtSearchBox.Size = dgvTotal.Columns(CInt(txtSearchBox.Tag)).HeaderCell.Size                
                    txtSearchBox.Visible = True                
                    txtSearchBox.Select()            
           End If        
      Catch ex As Exception            
        Debug.WriteLine(ex.ToString)        
      End Try    
    End Sub

    I am using VS2017 community edition, version 15.6.1, .NET framework 4.6.1.

    Thanks,

    Frank

    Friday, April 6, 2018 5:25 AM

Answers

  •  I am guessing that you mean that you are adding a TextBox control to the DataGridView's Control collection.  If that is so,  then you can try the following which will stop the problem you are having.

     There really is not a way to get rid of all the odd-n-end problems when you do things that where really never meant to be done,  such as this.  You would be much further ahead and would not need to hack a bunch of fixes together for these kind of problems if you used something like a Panel with the TextBox(s) in it at the top of the DataGridView.  You could even use a Right click on the column header to show a Panel with a TextBox in it above the DataGridView.  There are many fancy ways to do this.

     I know that sometimes as programmers/designers we get our minds set on a fancy look but,  sometimes we have to sacrifice a little and go with what works better.  8)

    Public Class Form1
        Private WithEvents TxtBx As New TextBox With {.Left = 0, .Top = 0}
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
            DataGridView1.ColumnHeadersHeight = 80
            DataGridView1.Controls.Add(TxtBx)
            For i As Integer = 1 To 10 Step 2
                DataGridView1.Rows.Add(New Object() {i.ToString, (i + 1).ToString})
            Next
        End Sub
    
        Private Sub TxtBx_Enter(sender As Object, e As EventArgs) Handles TxtBx.Enter
            DataGridView1.ReadOnly = True
        End Sub
    
        Private Sub TxtBx_Leave(sender As Object, e As EventArgs) Handles TxtBx.Leave
            DataGridView1.ReadOnly = False
        End Sub
    End Class
    


    If you say it can`t be done then i`ll try it

    • Marked as answer by frank_mel Tuesday, April 10, 2018 11:31 PM
    Tuesday, April 10, 2018 1:20 AM
  • I can't tell why this may be occuring according to this Default Keyboard and Mouse Handling in the Windows Forms DataGridView Control however using a TextBox TextChanged handler sub setting Focus to the TextBox worked. However on Full Row Select the first Cell of the first Row loses the selection color though the rest of the row maintains the selection color which is strange too. Maybe the first cell is in edit mode though programatically in the TextBox's text changed event sub you could take all cells out of edit mode that are in edit mode.

    Option Strict On
    
    Public Class Form1
    
        WithEvents MultiVarAnalysis As New DataTable("SixSigma") ' Create DataTable with events.
        WithEvents MVASS As New BindingSource ' Create BindingSource with events.
        WithEvents TextBox1 As New TextBox
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2)))
            DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
            DataGridView1.Anchor = CType(AnchorStyles.Bottom + AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top, AnchorStyles)
            DataGridView1.MultiSelect = False ' Don't want MultiSelect on for deleting rows.
            DataGridView1.AllowDrop = True
            DataGridView1.AutoSize = True
            DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
    
            MultiVarAnalysis.Columns.Add("Shift", GetType(String)) ' Represents FA
            MultiVarAnalysis.Columns("Shift").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Hello this is a long column", GetType(String)) ' Represents FB
            MultiVarAnalysis.Columns("Hello this is a long column").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Hour", GetType(String)) ' Represents FC
            MultiVarAnalysis.Columns("Hour").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Unit", GetType(String)) ' Represents FD
            MultiVarAnalysis.Columns("Unit").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Output", GetType(Double)) ' Represents Y
            MultiVarAnalysis.Columns("Output").AllowDBNull = False
    
    
            ' Add rows to DataTable
    
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U1", 0.947)
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U2", 5.427)
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U3", 8.334)
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U4", 4.637)
    
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U1", 4.766)
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U2", 4.461)
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U3", 5.791)
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U4", 2.313)
    
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U1", 4.804)
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U2", 5.238)
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U3", 5.767)
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U4", 5.108)
    
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U1", 3.829)
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U2", 5.539)
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U3", 8.18)
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U4", 4.86)
    
    
            MultiVarAnalysis.AcceptChanges() ' Update DataTable with new data I think.
            MVASS.DataSource = MultiVarAnalysis ' Set DataSource for BindingSource
            DataGridView1.DataSource = MVASS ' Provide DataGridView1 with DataSource
    
            For i = 0 To DataGridView1.ColumnCount - 1
                DataGridView1.Columns(i).SortMode = DataGridViewColumnSortMode.Automatic
            Next
    
            DataGridView1.Controls.Add(TextBox1)
            TextBox1.Visible = False
        End Sub
    
    
        Private Sub dgvTotal_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
            Try
                If e.Button = Windows.Forms.MouseButtons.Right Then
                    TextBox1.Select()
                    TextBox1.Focus()
                    TextBox1.Tag = e.ColumnIndex
                    TextBox1.Location = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, -1, False).Location
                    TextBox1.Size = DataGridView1.Columns(CInt(TextBox1.Tag)).HeaderCell.Size
                    TextBox1.Visible = True
                    TextBox1.Select()
                End If
            Catch ex As Exception
                Debug.WriteLine(ex.ToString)
            End Try
        End Sub
    
        Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
            TextBox1.Focus()
        End Sub
    
    End Class


    La vida loca

    • Edited by Mr. Monkeyboy Tuesday, April 10, 2018 4:38 PM
    • Marked as answer by frank_mel Tuesday, April 10, 2018 11:31 PM
    Tuesday, April 10, 2018 3:57 AM

All replies

  • Hi frank_mel,

    According to your question is more related Visual Basic, I will move it to Visual Basic forum for suitable support.

    The CLR Forum discuss and ask questions about .NET Framework Base Classes (BCL) such as Collections, I/O, Regigistry, Globalization, Reflection. Also discuss all the other Microsoft libraries that are built on or extend the .NET Framework, including Managed Extensibility Framework (MEF), Charting Controls, CardSpace, Windows Identity Foundation (WIF), Point of Sale (POS), Transactions. 

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, April 9, 2018 7:27 AM
  • Hello,

    Have you tried using EditingControlShowing and cast the current cell to a TextBox ? Simple starter

    Private Sub DataGridView1_EditingControlShowing( 
        sender As Object, 
        e As DataGridViewEditingControlShowingEventArgs) _ 
    Handles DataGridView1.EditingControlShowing 
    
        If DataGridView1.CurrentCell.IsComboBoxCell Then 
            If DataGridView1.Columns(DataGridView1.CurrentCell.ColumnIndex).Name = "SomeColumnName" Then 
                Dim tb As TextBox = TryCast(e.Control, TextBox) 
    
            End If 
        End If 
    End Sub 


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Monday, April 9, 2018 1:13 PM
    Moderator
  •  I am guessing that you mean that you are adding a TextBox control to the DataGridView's Control collection.  If that is so,  then you can try the following which will stop the problem you are having.

     There really is not a way to get rid of all the odd-n-end problems when you do things that where really never meant to be done,  such as this.  You would be much further ahead and would not need to hack a bunch of fixes together for these kind of problems if you used something like a Panel with the TextBox(s) in it at the top of the DataGridView.  You could even use a Right click on the column header to show a Panel with a TextBox in it above the DataGridView.  There are many fancy ways to do this.

     I know that sometimes as programmers/designers we get our minds set on a fancy look but,  sometimes we have to sacrifice a little and go with what works better.  8)

    Public Class Form1
        Private WithEvents TxtBx As New TextBox With {.Left = 0, .Top = 0}
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
            DataGridView1.ColumnHeadersHeight = 80
            DataGridView1.Controls.Add(TxtBx)
            For i As Integer = 1 To 10 Step 2
                DataGridView1.Rows.Add(New Object() {i.ToString, (i + 1).ToString})
            Next
        End Sub
    
        Private Sub TxtBx_Enter(sender As Object, e As EventArgs) Handles TxtBx.Enter
            DataGridView1.ReadOnly = True
        End Sub
    
        Private Sub TxtBx_Leave(sender As Object, e As EventArgs) Handles TxtBx.Leave
            DataGridView1.ReadOnly = False
        End Sub
    End Class
    


    If you say it can`t be done then i`ll try it

    • Marked as answer by frank_mel Tuesday, April 10, 2018 11:31 PM
    Tuesday, April 10, 2018 1:20 AM
  • I can't tell why this may be occuring according to this Default Keyboard and Mouse Handling in the Windows Forms DataGridView Control however using a TextBox TextChanged handler sub setting Focus to the TextBox worked. However on Full Row Select the first Cell of the first Row loses the selection color though the rest of the row maintains the selection color which is strange too. Maybe the first cell is in edit mode though programatically in the TextBox's text changed event sub you could take all cells out of edit mode that are in edit mode.

    Option Strict On
    
    Public Class Form1
    
        WithEvents MultiVarAnalysis As New DataTable("SixSigma") ' Create DataTable with events.
        WithEvents MVASS As New BindingSource ' Create BindingSource with events.
        WithEvents TextBox1 As New TextBox
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2)))
            DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
            DataGridView1.Anchor = CType(AnchorStyles.Bottom + AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top, AnchorStyles)
            DataGridView1.MultiSelect = False ' Don't want MultiSelect on for deleting rows.
            DataGridView1.AllowDrop = True
            DataGridView1.AutoSize = True
            DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
    
            MultiVarAnalysis.Columns.Add("Shift", GetType(String)) ' Represents FA
            MultiVarAnalysis.Columns("Shift").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Hello this is a long column", GetType(String)) ' Represents FB
            MultiVarAnalysis.Columns("Hello this is a long column").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Hour", GetType(String)) ' Represents FC
            MultiVarAnalysis.Columns("Hour").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Unit", GetType(String)) ' Represents FD
            MultiVarAnalysis.Columns("Unit").AllowDBNull = False
            MultiVarAnalysis.Columns.Add("Output", GetType(Double)) ' Represents Y
            MultiVarAnalysis.Columns("Output").AllowDBNull = False
    
    
            ' Add rows to DataTable
    
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U1", 0.947)
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U2", 5.427)
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U3", 8.334)
            MultiVarAnalysis.Rows.Add("A", "T1", "1st", "U4", 4.637)
    
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U1", 4.766)
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U2", 4.461)
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U3", 5.791)
            MultiVarAnalysis.Rows.Add("A", "T1", "2nd", "U4", 2.313)
    
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U1", 4.804)
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U2", 5.238)
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U3", 5.767)
            MultiVarAnalysis.Rows.Add("A", "T2", "1st", "U4", 5.108)
    
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U1", 3.829)
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U2", 5.539)
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U3", 8.18)
            MultiVarAnalysis.Rows.Add("A", "T2", "2nd", "U4", 4.86)
    
    
            MultiVarAnalysis.AcceptChanges() ' Update DataTable with new data I think.
            MVASS.DataSource = MultiVarAnalysis ' Set DataSource for BindingSource
            DataGridView1.DataSource = MVASS ' Provide DataGridView1 with DataSource
    
            For i = 0 To DataGridView1.ColumnCount - 1
                DataGridView1.Columns(i).SortMode = DataGridViewColumnSortMode.Automatic
            Next
    
            DataGridView1.Controls.Add(TextBox1)
            TextBox1.Visible = False
        End Sub
    
    
        Private Sub dgvTotal_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.ColumnHeaderMouseClick
            Try
                If e.Button = Windows.Forms.MouseButtons.Right Then
                    TextBox1.Select()
                    TextBox1.Focus()
                    TextBox1.Tag = e.ColumnIndex
                    TextBox1.Location = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, -1, False).Location
                    TextBox1.Size = DataGridView1.Columns(CInt(TextBox1.Tag)).HeaderCell.Size
                    TextBox1.Visible = True
                    TextBox1.Select()
                End If
            Catch ex As Exception
                Debug.WriteLine(ex.ToString)
            End Try
        End Sub
    
        Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
            TextBox1.Focus()
        End Sub
    
    End Class


    La vida loca

    • Edited by Mr. Monkeyboy Tuesday, April 10, 2018 4:38 PM
    • Marked as answer by frank_mel Tuesday, April 10, 2018 11:31 PM
    Tuesday, April 10, 2018 3:57 AM
  • Thanks Wendy, It is my first time ever to post in MSDN community and I think I get better idea about where to post what.

    Cheers,

    Frank

    Tuesday, April 10, 2018 6:35 AM
  • Frank,

    That is not normal, and because of the fact that the DataGridView is now at least used since a decade by hundred of thousands of persons there should be somewhere a bug in your program. 

    However, that is not in the code you show, you have to sear ch for code as that but then with a zero in it. 


    Success
    Cor

    Tuesday, April 10, 2018 6:56 AM
  • Frank,

    That is not normal, and because of the fact that the DataGridView is now at least used since a decade by hundred of thousands of persons there should be somewhere a bug in your program. 

    However, that is not in the code you show, you have to sear ch for code as that but then with a zero in it. 


    Success
    Cor


    I had the same problem with zero too Cor. Have no idea why typing zero in the TextBox causes the first cell in the first row to go into edit mode. I didn't test for all keyboard characters but zero causes that if it is first character typed. One or two did not cause it nor did a, b or c.

    La vida loca

    Tuesday, April 10, 2018 4:35 PM
  • Hi John,

    I've no 0 anymore written on the key, can I stop?

    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            dgvTotal.Rows.Add(1)
            dgvTotal.Rows(dgvTotal.Rows.Count - 2).Cells(0).Value = txtSearchBox.Text
            txtSearchBox.Text = ""
            txtSearchBox.Focus()
        End Sub
        Private Sub dgvTotal_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgvTotal.ColumnHeaderMouseClick
            Try
                If e.Button = Windows.Forms.MouseButtons.Right Then
                    txtSearchBox.Select()
                    txtSearchBox.Focus()
                    txtSearchBox.Tag = e.ColumnIndex
                    txtSearchBox.Location = dgvTotal.GetCellDisplayRectangle(e.ColumnIndex, -1, False).Location
                    txtSearchBox.Size = dgvTotal.Columns(CInt(txtSearchBox.Tag)).HeaderCell.Size
                    txtSearchBox.Visible = True
                    txtSearchBox.Select()
                End If
            Catch ex As Exception
                Debug.WriteLine(ex.ToString)
            End Try
        End Sub
    End Class

    It happened to me when I had not set the focus and was clicking on the wrong cell. (The datagridview cell)


    Success
    Cor


    Tuesday, April 10, 2018 5:34 PM
  •  Cor,  if you add the TextBox to the DataGridView's Control collection as Monkey and I showed,  you will see that when you set focus to the TextBox and press 0,  it will jump to the first cell of the DataGridView.  8)

     Oh... That is if you can get your 0 key to work again.  haha


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Tuesday, April 10, 2018 8:52 PM
    Tuesday, April 10, 2018 8:51 PM
  • Hi Ray,

    Maybe because it is late here, but I got it not done wrong with the code from John. Framework 4.7.2 

    However, you wrote it already, controls are made for normal use. I remember me than always this old joke. I've written this already a short while ago in this forum. An old lady invites the police. "Those people on the other side are doing dirty things," she says. "We don't see anything strange madam.", the police tells. "You've to stand on this chair to see it", says the old lady.   

    :-)


    Success
    Cor

    Tuesday, April 10, 2018 9:21 PM
  • Hi Ray,

    Maybe because it is late here, but I got it not done wrong with the code from John. Framework 4.7.2 

    However, you wrote it already, controls are made for normal use. I remember me than always this old joke. I've written this already a short while ago in this forum. An old lady invites the police. "Those people on the other side are doing dirty things," she says. "We don't see anything strange madam.", the police tells. "You've to stand on this chair to see it", says the old lady.   

    :-)


    Success
    Cor

    Hi Guys, 

    Thanks for all the information and I am happy that this observation could be repeated somewhere else so that I don't need to debug the code. I tried with .NET 4.7.1 which is the latest version available to me and cannot fix it. Looks like I have to find some other ways to get around this issue.

    Cheers,

    Frank

    Tuesday, April 10, 2018 11:06 PM
  • Hello Karen, 

    Thanks for your message and it is an new idea to me.  Because I used the textbox a lot almost everywhere that it means many change on current base. I prefer to add textbox.focus line in the textchanged event which avoids touching other codes.   But I keep the casting way in mind and will try it next time. 

    Thanks and regards,

    Frank

    Tuesday, April 10, 2018 11:30 PM
  • You are right and this is indeed a quick fix, thanks!
    Tuesday, April 10, 2018 11:34 PM
  • Thanks buddy, this is also a quick fix to help me out.
    Tuesday, April 10, 2018 11:35 PM