Quantcast
Channel: Windows Forms Data Controls and Databinding forum
Viewing all articles
Browse latest Browse all 2535

DataGridView raising SetCurrentCellAddressCore Exception

$
0
0
I've built an Enter-Firendly DataGridView control, which basically just treats the enter key as the tab key, allowing the user to move quickly between cells just by pressing enter.  It's very useful for accounting applications.

Anyway, it works fine when the user just uses the enter key, or the arrow keys, to move between cells.  It breaks down however when the user uses the mouse.  I get the error: Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.

Here is my code.  Sorry one piece is in VB while the other is in C#.  I had packaged the DataGridView extension into a class library, and used c# which is my prefered language, but the consuming application was already written in VB.

First the control:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace EnterFriendlyDataGridView
{
    public class DataGridViewEnter : DataGridView
    {
        public string lastColumn;
        public event EventHandler rowEntryComplete;

        //This override causes the DataGridView to use the enter key in a similar way as
        //the tab key

        protected override bool ProcessDialogKey(Keys keyData)
        {
            Keys key = (keyData & Keys.KeyCode);

            if (key == Keys.Enter)
            {
                return this.ProcessEnterKeyAsTab(keyData);
            }
            return base.ProcessDialogKey(keyData);
        }

        public bool ProcessEnterKeyAsTab(Keys keyData)
        {

            if (base.Columns[base.CurrentCell.ColumnIndex].Name == lastColumn)
            {
                // raise an event which, when handled, ends edit on the current cell
                if (rowEntryComplete != null)
                    rowEntryComplete(this, null);

                return true;
            }
            else
            {
                // possibly only do this if balances don't match
                return base.ProcessTabKey(keyData);
            }
        }

        protected override bool ProcessDataGridViewKey(KeyEventArgs e)
        {

            if (e.KeyCode == Keys.Enter)
                return this.ProcessEnterKeyAsTab(e.KeyData);
            else
                return base.ProcessDataGridViewKey(e);
        }

        public void manualHome()
        {
            base.ProcessHomeKey(Keys.Home);
        }

        public void manualTab()
        {
            base.ProcessTabKey(Keys.Tab);
        }
    }
}


And now the host application:

#Region "DataGridView methods"

    Private Sub dgvSerialNumbers_RowEntryComplete(ByVal sender As Object, ByVal e As EventArgs) Handles dgvSerialNumbers.rowEntryComplete
        'end edit mode, which fires the CellEndEdit event
        dgvSerialNumbers.BeginEdit(False)
        dgvSerialNumbers.EndEdit()

    End Sub

    Private Sub dgvSerialNumbers_CellClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dgvSerialNumbers.CellClick
        Dim a As Integer = 1
    End Sub

    Private Sub dgvSerialNumbers_CellEndEdit(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dgvSerialNumbers.CellEndEdit

        Dim fromSN, toSN As String
        If e.ColumnIndex = 0 Then

            fromSN = dgvSerialNumbers.Rows(e.RowIndex).Cells(0).Value

            If dgvSerialNumbers.Rows(e.RowIndex).Cells(1).Value = "" Then
                'Copy the From SN to the ToSN
                dgvSerialNumbers.Rows(e.RowIndex).Cells(1).Value = fromSN
                dgvSerialNumbers.manualTab()
                dgvSerialNumbers.BeginEdit(True)
            End If

        Else

            If dgvSerialNumbers.Rows(e.RowIndex).Cells(1).Value Is Nothing Then Exit Sub

            'this is where we interpolate To SN's based on From SN's
            fromSN = dgvSerialNumbers.Rows(e.RowIndex).Cells(0).Value
            toSN = dgvSerialNumbers.Rows(e.RowIndex).Cells(1).Value

            If toSN.Length < fromSN.Length Then
                toSN = fromSN.Substring(0, fromSN.Length - toSN.Length) + toSN
                dgvSerialNumbers.Rows(e.RowIndex).Cells(1).Value = toSN
            End If

            dgvSerialNumbers.manualTab()

        End If
    End Sub

#End Region

Viewing all articles
Browse latest Browse all 2535

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>