Einfügen von Excel-Text in der Zwischenablage, um Datengebundene DataGridView-und Entity Framework-Validierung

In einem Windows Forms-Projekt entwickelt in Visual Studio 2010, ich habe ein DataGridView an eine BindingSource, dessen DataSource ist eine BindingList(Of T). T ist eine Entität, einen Entity Framework 5 Modell.

Meine Entitäten implementieren von INotifyPropertyChanged und IDataErrorInfo.

Meinem Benutzer Excel-Köpfe und darauf bestehen, dass ich für das einfügen von Excel-Daten in die Netze verwenden in unserer Anwendung.

Also machte ich mich mit ein paar einfachen Regeln.

  1. Imitieren so genau wie möglich die copy & paste-Verhalten innerhalb von Excel.
  2. Einfügen von Daten in eine neue Zeile in einem DataGridView erstellen und validieren Sie neue Entitäten von der Art dargestellt, in der Startaufstellung.

Ich bin gekommen, einen langen Weg mit diesem, aber nun stieß gegen etwas, das ich nicht herausfinden können.

Urteilen, was Informationen, die ich finden kann, scheint es klar, dass, wenn das einfügen in eine gebundene, dass die zugrunde liegende Datenquelle sollte das Ziel von Ihr bearbeitet und erstellt.

Oder sollte es?

Ich habe beide Wege ausprobiert.

Wenn Sie auf die Zellen selbst, ich habe gehofft, dass ich schreiben konnte, die routine, so dass die überprüfung Ereignisse eingebaut DataGridView würde Feuer bei Bedarf, ob ich das Bearbeiten einer vorhandenen Zeile oder einen neuen zu erstellen.

Ich kurz entdeckt, dass es war nicht wie erwartet funktioniert, weil CellValidating nicht ausgelöst, bis die Zelle den Fokus verliert.

Beim einfügen, ich möchte überprüfen der Zelle auf den moment, in dem ein Wert ist eingefügt in es - cancelling-der rest der einfügen-operation, wenn es fehlschlägt.

Bei der Ausrichtung der zugrunde liegenden Datenquelle (eine Zeile DataBoundItem Besetzung der entsprechenden entity-Typ), ich kann neue Entitäten aus der Zwischenablage Daten und überprüfen Sie, bevor Sie änderungen an der DbContext.

In jedem Fall, wenn die Validierung fehlschlägt, wird das DataGridView verloren zu haben scheint der Vorherige Wert für die Zelle.

Wenn die Validierung fehlschlägt, wird der Benutzer aufgefordert wird, und die routine wird beendet. Ich möchte die Benutzer werden in der Lage, drücken Sie die Esc-Taste, um wieder den vorherigen Wert der Zelle, aber die Zelle bleibt leer.

Weiß jemand, warum der Vorherige Wert ist nicht mehr verfügbar, wenn die Bearbeitung einer Zelle, die den Wert programmatisch?

Hier ist, was ich Tue, so weit. Ich bin zwingen die überprüfung Ereignisse für Feuer durch aufrufen des Formulars .Validate-Methode. Ich weiß nicht, ob ich es tun sollte oder nicht. Es ist unvollständig, ich bin noch nicht mit neuen Zeilen:

    Private Sub PasteFromClipboard(ByVal sender As Object, ByVal e As KeyEventArgs)
    Dim dgv = TryCast(sender, DataGridView)

    If Not IsNothing(dgv) Then
        If dgv.SelectedCells.Count > 0 Then
            Dim rowSplitter = {ControlChars.Cr, ControlChars.Lf}
            Dim columnSplitter = {ControlChars.Tab}
            Dim topLeftCell = CopyPasteFunctions.GetTopLeftSelectedCell(dgv.SelectedCells)

            If Not IsNothing(topLeftCell) Then
                Dim data = Clipboard.GetData(DataFormats.Text)

                If Not IsNothing(data) Then
                    Dim columnIndex = topLeftCell.ColumnIndex
                    Dim rowIndex = topLeftCell.RowIndex
                    Dim columnCount = dgv.Columns.Count
                    Dim rowCount = dgv.Rows.Count

                    'Split clipboard data into rows
                    Dim rows = data.ToString.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries)

                    For i = 0 To rows.Length - 1
                        'Split row into cell values
                        Dim values = rows(i).Split(columnSplitter)

                        For j = 0 To values.Length - 1
                            If (j <= (columnCount - 1)) AndAlso (i <= (rowCount - 1)) Then
                                Dim cell = dgv.Rows(rowIndex + i).Cells(columnIndex + j)
                                dgv.CurrentCell = cell
                                dgv.BeginEdit(False)
                                cell.Value = values(j)

                                If Not Me.Validate() Then
                                    dgv.CancelEdit()
                                    Exit Sub
                                Else
                                    dgv.EndEdit()
                                End If
                            Else
                                Debug.Print(String.Format("RowIndex: {0}, ColumnIndex: {1}", i, j))
                            End If
                        Next
                    Next
                End If
            End If
        End If
    End If
End Sub

Public Module CopyPasteFunctions
Public Function GetTopLeftSelectedCell(ByVal cells As DataGridViewSelectedCellCollection) As DataGridViewCell
    If Not IsNothing(cells) AndAlso cells.Count > 0 Then
        Dim cellList = (From c In cells.Cast(Of DataGridViewCell)()
                        Order By c.RowIndex, c.ColumnIndex
                        Select c).ToList

        Return cellList(0)
    End If

    Return Nothing
End Function
End Module

Vielen Dank für jede Hilfe auf diesem. Hoffentlich andere arbeiten mit EF5 und Winforms. Wenn nicht, bin ich auf meiner eigenen!

InformationsquelleAutor jeff | 2013-08-01
Schreibe einen Kommentar