DataGrid - user edits

Sorry if this sounds a bit simple, but using a data grid in Visual Basic.net I'd like to be able to offer the user a chance to update their data once they have done some edits.  I do not seem to be able to find an event that fires when this happens!  Has anyone accomplished this simple task

Answer this question

DataGrid - user edits

  • akks

    Thanks.

    I have a similar kind of problem with my datagrid.

    I need to save the changes using a button. If i press the save  button after editing keeping the focus on the edited cell(without changes the focus prior to this event) i am getting HasChanges as false.

    I tried this code but still it don't work.


  • Temple

    I too am attempting to enable an update button when a user starts editing a field. Is this possible in a generic fashion in .Net
  • Len Miller

    Thanks.  

    I have an update button, but I wanted it to be disabled if there was nothing to update and enabled as soon as anything changed.  Your solution puts me a big step nearer - I can enable the button when they exit the cell.  I am left wondering what the TextChanged event of the data grid is supposed to do.  It does not fire when the text of a cell changes.

  • 10e

    Are you trying to offer them the possibility of saving data once they make changes and move off the current row  If that's the case, look at events of the CurrencyManager object bound to the datagrid. (Specifically, the PositionChanged event, watching the HasChanges property of the DataSet filling the DataGrid).

    Here's an example form, using data from the Northwind sample database, that demonstrates a simple version of the technique:
    Public Class Form4
      Inherits System.Windows.Forms.Form

    #Region " Windows Form Designer generated code "

      Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

      End Sub

      'Form overrides dispose to clean up the component list.
      Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
          If Not (components Is Nothing) Then
            components.Dispose()
          End If
        End If
        MyBase.Dispose(disposing)
      End Sub

      'Required by the Windows Form Designer
      Private components As System.ComponentModel.IContainer

      'NOTE: The following procedure is required by the Windows Form Designer
      'It can be modified using the Windows Form Designer.  
      'Do not modify it using the code editor.
      Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
      Friend WithEvents SqlDataAdapter1 As System.Data.SqlClient.SqlDataAdapter
      Friend WithEvents SqlSelectCommand1 As System.Data.SqlClient.SqlCommand
      Friend WithEvents SqlInsertCommand1 As System.Data.SqlClient.SqlCommand
      Friend WithEvents SqlUpdateCommand1 As System.Data.SqlClient.SqlCommand
      Friend WithEvents SqlDeleteCommand1 As System.Data.SqlClient.SqlCommand
      Friend WithEvents SqlConnection1 As System.Data.SqlClient.SqlConnection
      <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.DataGrid1 = New System.Windows.Forms.DataGrid()
        Me.SqlDataAdapter1 = New System.Data.SqlClient.SqlDataAdapter()
        Me.SqlDeleteCommand1 = New System.Data.SqlClient.SqlCommand()
        Me.SqlConnection1 = New System.Data.SqlClient.SqlConnection()
        Me.SqlInsertCommand1 = New System.Data.SqlClient.SqlCommand()
        Me.SqlSelectCommand1 = New System.Data.SqlClient.SqlCommand()
        Me.SqlUpdateCommand1 = New System.Data.SqlClient.SqlCommand()
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'DataGrid1
        '
        Me.DataGrid1.Anchor = (((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right)
        Me.DataGrid1.DataMember = ""
        Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
        Me.DataGrid1.Location = New System.Drawing.Point(8, 8)
        Me.DataGrid1.Name = "DataGrid1"
        Me.DataGrid1.Size = New System.Drawing.Size(272, 256)
        Me.DataGrid1.TabIndex = 1
        '
        'SqlDataAdapter1
        '
        Me.SqlDataAdapter1.DeleteCommand = Me.SqlDeleteCommand1
        Me.SqlDataAdapter1.InsertCommand = Me.SqlInsertCommand1
        Me.SqlDataAdapter1.SelectCommand = Me.SqlSelectCommand1
        Me.SqlDataAdapter1.TableMappings.AddRange(New System.Data.Common.DataTableMapping() {New System.Data.Common.DataTableMapping("Table", "Customers", New System.Data.Common.DataColumnMapping() {New System.Data.Common.DataColumnMapping("CustomerID", "CustomerID"), New System.Data.Common.DataColumnMapping("ContactName", "ContactName"), New System.Data.Common.DataColumnMapping("ContactTitle", "ContactTitle")})})
        Me.SqlDataAdapter1.UpdateCommand = Me.SqlUpdateCommand1
        '
        'SqlDeleteCommand1
        '
        Me.SqlDeleteCommand1.CommandText = "DELETE FROM Customers WHERE (CustomerID = @Original_CustomerID) AND (ContactName " & _
        "= @Original_ContactName OR @Original_ContactName IS NULL AND ContactName IS NULL" & _
        ") AND (ContactTitle = @Original_ContactTitle OR @Original_ContactTitle IS NULL A" & _
        "ND ContactTitle IS NULL)"
        Me.SqlDeleteCommand1.Connection = Me.SqlConnection1
        Me.SqlDeleteCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_CustomerID", System.Data.SqlDbType.NVarChar, 5, System.Data.ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), "CustomerID", System.Data.DataRowVersion.Original, Nothing))
        Me.SqlDeleteCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_ContactName", System.Data.SqlDbType.NVarChar, 30, System.Data.ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), "ContactName", System.Data.DataRowVersion.Original, Nothing))
        Me.SqlDeleteCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_ContactTitle", System.Data.SqlDbType.NVarChar, 30, System.Data.ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), "ContactTitle", System.Data.DataRowVersion.Original, Nothing))
        '
        'SqlConnection1
        '
        Me.SqlConnection1.ConnectionString = "data source=.;initial catalog=Northwind;integrated security=SSPI;persist security" & _
        " info=False;"
        '
        'SqlInsertCommand1
        '
        Me.SqlInsertCommand1.CommandText = "INSERT INTO Customers(CustomerID, ContactName, ContactTitle) VALUES (@CustomerID," & _
        " @ContactName, @ContactTitle); SELECT CustomerID, ContactName, ContactTitle FROM" & _
        " Customers WHERE (CustomerID = @CustomerID)"
        Me.SqlInsertCommand1.Connection = Me.SqlConnection1
        Me.SqlInsertCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@CustomerID", System.Data.SqlDbType.NVarChar, 5, "CustomerID"))
        Me.SqlInsertCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@ContactName", System.Data.SqlDbType.NVarChar, 30, "ContactName"))
        Me.SqlInsertCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@ContactTitle", System.Data.SqlDbType.NVarChar, 30, "ContactTitle"))
        '
        'SqlSelectCommand1
        '
        Me.SqlSelectCommand1.CommandText = "SELECT CustomerID, ContactName, ContactTitle FROM Customers"
        Me.SqlSelectCommand1.Connection = Me.SqlConnection1
        '
        'SqlUpdateCommand1
        '
        Me.SqlUpdateCommand1.CommandText = "UPDATE Customers SET CustomerID = @CustomerID, ContactName = @ContactName, Contac" & _
        "tTitle = @ContactTitle WHERE (CustomerID = @Original_CustomerID) AND (ContactNam" & _
        "e = @Original_ContactName OR @Original_ContactName IS NULL AND ContactName IS NU" & _
        "LL) AND (ContactTitle = @Original_ContactTitle OR @Original_ContactTitle IS NULL" & _
        " AND ContactTitle IS NULL); SELECT CustomerID, ContactName, ContactTitle FROM Cu" & _
        "stomers WHERE (CustomerID = @CustomerID)"
        Me.SqlUpdateCommand1.Connection = Me.SqlConnection1
        Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@CustomerID", System.Data.SqlDbType.NVarChar, 5, "CustomerID"))
        Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@ContactName", System.Data.SqlDbType.NVarChar, 30, "ContactName"))
        Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@ContactTitle", System.Data.SqlDbType.NVarChar, 30, "ContactTitle"))
        Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_CustomerID", System.Data.SqlDbType.NVarChar, 5, System.Data.ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), "CustomerID", System.Data.DataRowVersion.Original, Nothing))
        Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_ContactName", System.Data.SqlDbType.NVarChar, 30, System.Data.ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), "ContactName", System.Data.DataRowVersion.Original, Nothing))
        Me.SqlUpdateCommand1.Parameters.Add(New System.Data.SqlClient.SqlParameter("@Original_ContactTitle", System.Data.SqlDbType.NVarChar, 30, System.Data.ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), "ContactTitle", System.Data.DataRowVersion.Original, Nothing))
        '
        'Form4
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.DataGrid1})
        Me.Name = "Form4"
        Me.Text = "Form2"
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

      End Sub

    #End Region

      Private WithEvents cm As CurrencyManager
      Private ds As New DataSet()

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
      End Sub


      Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        SqlDataAdapter1.Fill(ds)
        DataGrid1.DataSource = ds
        DataGrid1.DataMember = "Customers"
        cm = DirectCast(Me.BindingContext(ds, "Customers"), CurrencyManager)
      End Sub

      Private Sub cm_PositionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cm.PositionChanged
        If ds.HasChanges Then
          If MessageBox.Show("Do you want to save your changes ", "Handle Changes", MessageBoxButtons.YesNo) = DialogResult.Yes Then
            SqlDataAdapter1.Update(ds)
            cm.EndCurrentEdit()
          End If
        End If
      End Sub
    End Class
    All things being equal, I have a feeling most users will find this interface pretty irritating. It might be worth considering saving the updates on a button click, or when you close the form. But it's up to you. Also note that this is the simplest possible implementation of the concept, and needs some optmizing for real work. 

  • DataGrid - user edits