Avatar of emi_sastra
emi_sastra

asked on 

GridView Navigation Problem

Hi,

Please help fixing my code?

It cause problem when press Enter at 1st cell of 2nd row. It just hanging there.

Thank you.
Option Explicit On
 
Public Class frmMain
 
    Dim intCurrentRow As Integer = 0
    Dim intCurrentColumn As Integer = 0
 
    Delegate Sub SetColumnIndex(ByVal i As Integer)
    
    Private Sub Create_Grid_Column()
 
        Dim dgvItemCode As New DataGridViewTextBoxColumn
 
        Add_Column("ItemCode", "Code", 0, dgvItemCode, DataGridView1)
 
        Dim dgvItemName As New DataGridViewTextBoxColumn
        Add_Column("ItemName", "Name", 1, dgvItemName, DataGridView1)
 
        Dim dgvItemQty As New DataGridViewTextBoxColumn
        Add_Column("ItemQty", "Qty", 2, dgvItemQty, DataGridView1)
 
    End Sub
 
    Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 
        Me.StartPosition = FormStartPosition.CenterScreen
 
        With DataGridView1
            .EditMode = DataGridViewEditMode.EditProgrammatically
            .AllowUserToAddRows = False
        End With
 
        Create_Grid_Column()
 
        Add_Row(DataGridView1)
        Add_Row(DataGridView1)
 
    End Sub
 
    Private Sub DataGridView1_CellBeginEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit
 
        With DataGridView1
 
            If e.RowIndex <> intCurrentRow Then
 
                intCurrentColumn += 1
                Dim method As New SetColumnIndex(AddressOf Grid_Navigation)
 
                Me.DataGridView1.BeginInvoke(method, intCurrentRow)
 
            End If
 
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.FromArgb(255, 128, 0)
 
        End With
 
    End Sub
 
    Private Sub Grid_Navigation(ByVal RowIndex As Integer)
        With DataGridView1
 
            If .CurrentCell.ColumnIndex < .Columns.Count - 1 Then
                .CurrentCell = DataGridView1.Rows(RowIndex).Cells(intCurrentColumn)
            Else
                intCurrentRow += 1
                .CurrentCell = DataGridView1.Rows(intCurrentRow).Cells(0)
            End If
 
            .BeginEdit(True)
 
        End With
 
    End Sub
 
    Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
        With DataGridView1
            .BeginEdit(True)
        End With
    End Sub
 
    Private Sub DataGridView1_CellLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellLeave
 
        With DataGridView1
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.White
        End With
 
    End Sub
 
    Public Sub Add_Column(ByVal strColumnName As String, _
                             ByVal strHeaderName As String, _
                             ByVal intDisplayIndex As Integer, _
                             ByVal dgvTextColumn As DataGridViewTextBoxColumn, _
                             ByVal dgvName As DataGridView)
 
        With dgvName
 
            dgvTextColumn.DisplayIndex = intDisplayIndex
            dgvTextColumn.HeaderText = strHeaderName
            dgvTextColumn.DataPropertyName = strColumnName
            dgvTextColumn.Name = strColumnName
 
            .Columns.Add(dgvTextColumn)
 
        End With
 
    End Sub
 
    Public Sub Add_Row(ByVal dgvName As DataGridView)
 
        With dgvName
            .Rows.Add()
        End With
 
    End Sub
   
End Class

Open in new window

Visual Basic.NET

Avatar of undefined
Last Comment
emi_sastra
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

Hi emi_sastra,

Why do use CellBeginEdit() event to navigate instead of keydown/keypress/keyup ?

Just curiosity before continue.
Avatar of emi_sastra
emi_sastra

ASKER

Hi jpaulino,

I am sorry, just back.

Why do use CellBeginEdit() event to navigate instead of keydown/keypress/keyup ?

When I press Enter, it goes to cellLeave, cellEnter, cellBeginEdit, never goto Keydown event?

Thank you.
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

Ok, but when you press any key (like enter) you fire that keyboard events.

You want to move to the next column instead of next row after enter and color the current selection cell ?

Is this only or do you have another goal ?
Avatar of emi_sastra
emi_sastra

ASKER

Yes, I want to treat Enter Key like Tab key and also the color of selection cell, just like that.

Thank you.
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

Try this way:
Option Explicit On
 
Public Class frmMain
 
    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
 
        If keyData = Keys.Enter And Me.DataGridView1.IsCurrentCellInEditMode Then
            SendKeys.Send("{TAB}")
            Return True
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
 
    End Function
 
 
    Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
        If e.KeyCode = Keys.Enter Then
            e.SuppressKeyPress = True
            SendKeys.Send("{TAB}")
        End If
    End Sub
 
 
 
    Private Sub Create_Grid_Column()
 
        Dim dgvItemCode As New DataGridViewTextBoxColumn
 
        Add_Column("ItemCode", "Code", 0, dgvItemCode, DataGridView1)
 
        Dim dgvItemName As New DataGridViewTextBoxColumn
        Add_Column("ItemName", "Name", 1, dgvItemName, DataGridView1)
 
        Dim dgvItemQty As New DataGridViewTextBoxColumn
        Add_Column("ItemQty", "Qty", 2, dgvItemQty, DataGridView1)
 
    End Sub
 
    Public Sub Add_Row(ByVal dgvName As DataGridView)
        With dgvName
            .Rows.Add()
        End With
    End Sub
 
    Public Sub Add_Column(ByVal strColumnName As String, _
                                 ByVal strHeaderName As String, _
                                 ByVal intDisplayIndex As Integer, _
                                 ByVal dgvTextColumn As DataGridViewTextBoxColumn, _
                                 ByVal dgvName As DataGridView)
 
        With dgvName
            dgvTextColumn.DisplayIndex = intDisplayIndex
            dgvTextColumn.HeaderText = strHeaderName
            dgvTextColumn.DataPropertyName = strColumnName
            dgvTextColumn.Name = strColumnName
 
            .Columns.Add(dgvTextColumn)
        End With
    End Sub
 
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        Me.StartPosition = FormStartPosition.CenterScreen
 
        With DataGridView1
            .EditMode = DataGridViewEditMode.EditProgrammatically
            .AllowUserToAddRows = False
        End With
 
        Create_Grid_Column()
 
        Add_Row(DataGridView1)
        Add_Row(DataGridView1)
 
    End Sub
 
 
    Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
        With DataGridView1
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.FromArgb(255, 128, 0)
            .BeginEdit(True)
        End With
    End Sub
 
 
    Private Sub DataGridView1_CellLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellLeave
        With DataGridView1
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.White
        End With
    End Sub
 
End Class

Open in new window

Avatar of emi_sastra
emi_sastra

ASKER

Yes, it works, but get message from ZoneLab.
Could we solve this problem?

By the way, why my code can not work at the  second row?

Thank you.
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

>> Yes, it works, but get message from ZoneLab.

Don't understand what you nean. What is ZoneLab ?
Avatar of emi_sastra
emi_sastra

ASKER

it is firewall for internet protection.
ZoneLab is Zone Alarm.

Thank you.
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

It as started now ? It's the first time I head that :)

Probably is because of ProcessCmdKey that is subclassing. You can add your app as an exception of the firewall.

No problems with Panda, McAfee, NOD and Kaspersky (the ones that I know)
Avatar of emi_sastra
emi_sastra

ASKER

Ok.

But still have problem if I add more events to the code like validated or endedit. It just hanging there.

Thank you.
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

You have to show me the last version of you code. I don't know what events your're using.
Avatar of emi_sastra
emi_sastra

ASKER

The DataGridView1_KeyDown event never get called?

After I press Enter then it just hanging there, after I press Ctrl-Alt_Del, then I goes to DataGridView1_CellEndEdit at case 0 where I set a trace mark there.

Go to CellLeave, CellBeginEdit and back again to CellEndEdit at case 2 and problem after that.

Thank you.

Option Explicit On
 
Public Class frmMain
 
    Dim intCurrentRow As Integer = 0
    Dim intCurrentColumn As Integer = 0
 
    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
 
        If keyData = Keys.Enter And Me.DataGridView1.IsCurrentCellInEditMode Then
            SendKeys.Send("{TAB}")
            Return True
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
 
    End Function
 
    Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
 
        intCurrentRow = e.RowIndex
        intCurrentColumn = e.ColumnIndex
 
        With DataGridView1
 
            Select Case intCurrentColumn
 
                Case 0
 
                    .CurrentCell = .Rows(intCurrentRow).Cells(intCurrentColumn + 2)
                    .BeginEdit(True)
 
                Case 2
 
                    .CurrentCell = .Rows(intCurrentRow + 1).Cells(1)
                    .BeginEdit(True)
 
            End Select
 
        End With
 
    End Sub
 
 
    Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
        If e.KeyCode = Keys.Enter Then
            e.SuppressKeyPress = True
            SendKeys.Send("{TAB}")
        End If
     
    End Sub
 
 
 
    Private Sub Create_Grid_Column()
 
        Dim dgvItemCode As New DataGridViewTextBoxColumn
 
        Add_Column("ItemCode", "Code", 0, dgvItemCode, DataGridView1)
 
        Dim dgvItemName As New DataGridViewTextBoxColumn
        Add_Column("ItemName", "Name", 1, dgvItemName, DataGridView1)
 
        Dim dgvItemQty As New DataGridViewTextBoxColumn
        Add_Column("ItemQty", "Qty", 2, dgvItemQty, DataGridView1)
 
    End Sub
 
    Public Sub Add_Row(ByVal dgvName As DataGridView)
        With dgvName
            .Rows.Add()
        End With
    End Sub
 
    Public Sub Add_Column(ByVal strColumnName As String, _
                                 ByVal strHeaderName As String, _
                                 ByVal intDisplayIndex As Integer, _
                                 ByVal dgvTextColumn As DataGridViewTextBoxColumn, _
                                 ByVal dgvName As DataGridView)
 
        With dgvName
            dgvTextColumn.DisplayIndex = intDisplayIndex
            dgvTextColumn.HeaderText = strHeaderName
            dgvTextColumn.DataPropertyName = strColumnName
            dgvTextColumn.Name = strColumnName
 
            .Columns.Add(dgvTextColumn)
        End With
    End Sub
 
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        Me.StartPosition = FormStartPosition.CenterScreen
 
        With DataGridView1
            .EditMode = DataGridViewEditMode.EditProgrammatically
            .AllowUserToAddRows = False
        End With
 
        Create_Grid_Column()
 
        Add_Row(DataGridView1)
        Add_Row(DataGridView1)
 
    End Sub
 
 
    Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
        With DataGridView1
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.FromArgb(255, 128, 0)
            .BeginEdit(True)
        End With
    End Sub
 
 
    Private Sub DataGridView1_CellLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellLeave
        With DataGridView1
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.White
        End With
    End Sub
 
    
End Class

Open in new window

Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

But you have mixed the code I showed you and your old one.

Try only my code that does the trick. You're still using CellEndEdit try to remove it.
Avatar of emi_sastra
emi_sastra

ASKER

Yes, the code you showed me works.

But for entry data at datagridview I need to add some more code to do make it works perfect. Like some validation or moving to certain columns and rows as necessary.

Please help for this.

Thank you.
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

Ok, just say it what validation or moving you want to do.
Avatar of emi_sastra
emi_sastra

ASKER

Please see my code below.
May I code for wrong event.

If I press Enter at Item column then I will move to Qty column after doing some validation.
If I press Enter at the last column (Qty)  than I will add grid row (if necessary) and move to next row at first column.

Thank you.
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
 
        intCurrentRow = e.RowIndex
        intCurrentColumn = e.ColumnIndex
 
        With DataGridView1
 
            Select Case intCurrentColumn
 
                Case 0
 
                    .CurrentCell = .Rows(intCurrentRow).Cells(intCurrentColumn + 2)
                    .BeginEdit(True)
 
                Case 2
 
                    .CurrentCell = .Rows(intCurrentRow + 1).Cells(1)
                    .BeginEdit(True)
 
            End Select
 
        End With
 
    End Sub

Open in new window

Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

Try this:
Option Explicit On
 
Public Class frmMain
 
    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
 
        If keyData = Keys.Enter Then 'And Me.DataGridView1.IsCurrentCellInEditMode Then
            With DataGridView1
                Select Case .CurrentCell.ColumnIndex
                    Case 0
                        .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 2)
                    Case 2
                        If .CurrentCell.RowIndex + 1 = .RowCount Then Add_Row(DataGridView1)
                        .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(0)
                    Case Else
                        SendKeys.Send("{TAB}")
                End Select
                .BeginEdit(True)
            End With
            Return True
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
 
    End Function
 
 
    Private Sub Create_Grid_Column()
 
        Dim dgvItemCode As New DataGridViewTextBoxColumn
 
        Add_Column("ItemCode", "Code", 0, dgvItemCode, DataGridView1)
 
        Dim dgvItemName As New DataGridViewTextBoxColumn
        Add_Column("ItemName", "Name", 1, dgvItemName, DataGridView1)
 
        Dim dgvItemQty As New DataGridViewTextBoxColumn
        Add_Column("ItemQty", "Qty", 2, dgvItemQty, DataGridView1)
 
    End Sub
 
    Public Sub Add_Row(ByVal dgvName As DataGridView)
        With dgvName
            .Rows.Add()
        End With
    End Sub
 
    Public Sub Add_Column(ByVal strColumnName As String, _
                                 ByVal strHeaderName As String, _
                                 ByVal intDisplayIndex As Integer, _
                                 ByVal dgvTextColumn As DataGridViewTextBoxColumn, _
                                 ByVal dgvName As DataGridView)
 
        With dgvName
            dgvTextColumn.DisplayIndex = intDisplayIndex
            dgvTextColumn.HeaderText = strHeaderName
            dgvTextColumn.DataPropertyName = strColumnName
            dgvTextColumn.Name = strColumnName
 
            .Columns.Add(dgvTextColumn)
        End With
    End Sub
 
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        Me.StartPosition = FormStartPosition.CenterScreen
 
        With DataGridView1
            .EditMode = DataGridViewEditMode.EditProgrammatically
            .AllowUserToAddRows = False
        End With
 
        Create_Grid_Column()
 
        Add_Row(DataGridView1)
        Add_Row(DataGridView1)
 
    End Sub
 
 
    Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
        With DataGridView1
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.FromArgb(255, 128, 0)
            .BeginEdit(True)
        End With
    End Sub
 
 
    Private Sub DataGridView1_CellLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellLeave
        With DataGridView1
            .Rows(e.RowIndex).Cells(e.ColumnIndex).Style.BackColor = Color.White
        End With
    End Sub
 
End Class

Open in new window

Avatar of emi_sastra
emi_sastra

ASKER

Hi jpaulino,

I am sorry, just back again.

I works great. How to force stay at current cell if the current cell is empty?

        Dim dgvRow As DataGridViewRow = .Rows(.CurrentRow.Index)
        Dim strData As String = dgvRow.Cells(.CurrentCell.ColumnIndex).Value

why strData always return nothing?

Please see the some code I add to your code.
         

Thank you.
   Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
 
        If keyData = Keys.Enter Then
 
            With DataGridView1
 
                Select Case .CurrentCell.ColumnIndex
 
                    Case 0
                        Dim dgvRow As DataGridViewRow = .Rows(.CurrentRow.Index)
 
                        Dim strData As String = dgvRow.Cells(.CurrentCell.ColumnIndex).Value
 
                        If strData Is Nothing Then strData = ""
 
                        If strData.Trim = "" Then
 
                            'Stay At current cell
                        Else
 
                            .CurrentCell = .Rows(.CurrentCell.RowIndex).Cells(.CurrentCell.ColumnIndex + 2)
                        End If
                    Case 2
                        If .CurrentCell.RowIndex + 1 = .RowCount Then Add_Row(DataGridView1)
                        .CurrentCell = .Rows(.CurrentCell.RowIndex + 1).Cells(0)
                    Case Else
                        SendKeys.Send("{TAB}")
                End Select
 
                .BeginEdit(True)
            End With
 
            Return True
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If
 
    End Function

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Jorge Paulino
Jorge Paulino
Flag of Portugal image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of emi_sastra
emi_sastra

ASKER

It works! Great help!

Thank you very much for your help.
Visual Basic.NET
Visual Basic.NET

Visual Basic .NET (VB.NET) is an object-oriented programming language implemented on the .NET framework, but also supported on other platforms such as Mono and Silverlight. Microsoft launched VB.NET as the successor to the Visual Basic language. Though it is similar in syntax to Visual Basic pre-2002, it is not the same technology,

96K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo