Each time a user changes a value in one of the editable columns within my DataGridView, it triggers a recalculation of up to 8 fields. This means the event CellValueChanged Event on the DataGridView will trigger more than 1 time.
I want to create a row in a DataSet.DataTable which will include the new values for all columns after the user has changed a value.
The issue I am having is that the code below creates a row for each column that has had its value changed due to the recalculated columns.
Private Sub PL_DGV_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles PL_DGV.CellValueChanged
If isLoaded Then
Dim grid_row As DataRow = Me.DataSet.PL.Rows(e.RowIndex)
Dim unsaved_row As DataRow = grid_row
Me.DataSet.PL_UnsavedChanges.ImportRow(unsaved_row)
unsaved_changes = True
End If
End Sub
How could I make it so that if a row already exists, it will just update the values within it each time?
There is no PrimaryKeys assigned to the DataTable within the DataSet, but there are 3 columns which would be used as unique values per row.
[UPDATE BASED ON COMMENTS]
With the code shown above what will happen is that the user will update a value in column 1 >
Event is triggered and new row is created which will include the new value in Column 1 >
Column 2 is recalculated based on changes in Column 1 >
Event is triggered and new row is created which will include the new value in Column 1 and Column 2 >
Column 3 is recalculated based on changes on either of the previously mentioned columns >
Event is triggered and new row is created which will include new value in Column 1, Column 2 and Column 3.
What I want to achieve is to have 1 row which will have all the new values, no need to generate any other rows but one which includes the changes from the user action and any recalculations based on that.
After the discussion within the comments the solution to my issue, or rather what I did to overcome it was the below:
Dim grid_row As DataRow = Me.DataSet.PL.Rows(e.RowIndex)
Dim Column1 = Variable1
Dim Column2 = grid_row.Item("Column2").ToString().Trim()
Dim Column3 = grid_row.Item("Column3").ToString().Trim()
Dim Updated_column_name = Me.DataSet.PL.Columns(e.ColumnIndex).ColumnName
Dim Updated_value = grid_row.Item(Updated_column_name).ToString()
Dim row As DataRow = Me.DataSet.PL_ChangesLog.NewRow()
row("price_list") = Price_list
row("warehouse") = Warehouse
row("product_code") = Product
row("column_name") = Updated_column_name
row("updated_value") = Updated_value
row("timestamp") = DateTime.Now()
row("username") = Environment.UserName()
Me.DataSet.PL_ChangesLog.Rows.Add(row)
unsaved_changes = True
This allows me to create a DataTable holding a row of data for each cell that has had its value updated, whether recalculated via code or by user action.
Based on that I can pick out the last audit and use that as the "Save Changes" to commit the changes to the SQL Database.
Related
I'm currently stuck on inserting a value into a row in datagridview in vb.net
My code is:
Dim subtotal As Integer = Val(adult.Text) * 500 + Val(child.Text) * 300
For Each row As DataGridViewRow In DataGridView2.Rows
row.Cells.Insert(subtotal)
Next
It supposed to be like this.
enter image description here
Hint I wanna do it like this
You don't insert a new cell. You get an existing cell in the appropriate column and set its Value property. This line:
row.Cells.Insert(subtotal)
would be like this:
row.Cells(columnIndex).Value = subtotal
That said, that will put the same value in every row. That's probably not what you want but it's all we can you based on the information you've provided. If what you actually expect is to get a different value for each row based on data in that row then the calculation would have to be inside the loop as well, e.g.
Dim adultCount = CInt(row.Cells(adultColumnIndex).Value)
Dim childCount = CInt(row.Cells(childColumnIndex).Value)
Dim subtotal = adultCount * 500 + childCount * 300
row.Cells(subtotalColumnIndex).Value = subtotal
Of course, if you had bound this grid to a DataTable then you could set the Expression property of the DataColumn for the subtotal and it would be calculated automatically.
I have a database table which contains a list of usernames and their current active location, an integer called SEQUENCE.
I get this list of sequence numbers into a datatable with a single column (e.g. "SELECT SEQUENCE FROM TABLE"):
dtUsers = CLS_USERS.GetUsers(User)
It excludes the current user, which is why I parse in User.
What I then do is loop through the datatable and for each number I want to set the matching row in a datagridview (which also has a SEQUENCE column) to a different colour. This is my current code:
For Each row As DataRow In dtUsers.Rows
intSeq = row("SEQUENCE")
For Each dgv_row As DataGridViewRow In dgvCandList.Rows
If dgv_row.Cells("CURRENT_SQ").Value = intSeq Then
dgv_row.DefaultCellStyle.BackColor = Color.Cyan
Else
dgv_row.DefaultCellStyle.BackColor = Color.Grey
End If
Next
Next
However, all rows are highlighted rather than just those where dgv_row.Cells("SV_CURRENT_CAND_SQ").Value = intSeq is True... I've verified that this loop is working correctly, so it must be dgv_row.DefaultCellStyle.BackColor = Color.Cyan which is incorrect?
If so, how should I correctly be assigning the row back colour of specific DataGridRow?
EDIT: This code works correctly, my issue was related to bug outside this loop causing the BackColor to be sent for everything, and then never setback to default if where BackColor wasn't being set back to the default if it wasn't in dtUsers.
I have a SQL database with a table "Employees" in it (with large number of rows). By using DataGridView, I want to search for specific "Employee's Name" and change it's "Job". How can I achieve that. I'm using VB.net. Please Help Me.
Not sure if this will help but write a loop that goes through all the values if it finds a match its true if not it is false ,if found the item can be displayed in a textbox and edited
if not a message is displayed saying "no match found"
the editing part can be done using a procedure that will update the value in your grid with what is entered
i can supply code for this if need be but i am unsure if this is what you wish
and there is most likely a better way of doing it
you can loop through your grid, and check if the data you wish to edit exists using the For loop:
Supposing you are using a textbox as the input, and you use a label to hold the employee ID:
Dim EmpIDColumn as Integer = 'array number of your EmpID Column
Dim EmpNameColumn as Integer = 'The array number of the column where your EmpName is
Dim JobColumn as Integer = 'The array number of your job column
For each dr as Datagridviewrow in Datagridview1.Rows
If dr.cells(EmpNameColumn).value = TxtSearchBox.text Then
txtEmpJob.text = dr.cells(JobColumn).value
lblEmpID.Text = dr.cells(EmpIDColumn).value
End if
Next
Okay, so you've searched the record successfully. Next step (after editing the job, and even other details like the name) would be to update the record in the grid. Remember you set the lblEmpID's text to empID in the column? Use it to find the
Record you wish to change in the grid using the same technique above!
Dim EmpIDColumn as Integer = 'array number of your EmpID Column
Dim EmpNameColumn as Integer = 'The array number of the column where your EmpName is
Dim JobColumn as Integer = 'The array number of your job column
For each dr as Datagridviewrow in Datagridview1.Rows
If dr.cells(EmpIDColumn).value = lblEmpID.text Then
dr.cells(JobColumn).value = txtEmpJob.text
dr.cells(EmpNameColumn).value = txtEmpName.text
'then, type in here your SQL Query Update!
End if
Next
I am stuck in a situation where I need to disable a few columns in each row, except for the newly added row.
That is, I have 10 columns in the grid and the first 3 columns are databound and come from the database as disabled or read-only. The rest are editable.
If I add a new row, then all the columns of the new row must be enabled until it is saved.
I don't have any DataKey or primary key for my existing row or the new row. I have to check for some boolean value like IsNewRow.
In my current scenario I am using this code block:
Private Sub dgTimeSheet_InitializeRow(ByVal sender As Object, ByVal e As Infragistics.Win.UltraWinGrid.InitializeRowEventArgs) Handles dgTimeSheet.InitializeRow
''if either column key is Project, Class or Milestone
'' Activation.NoEdit = Disable and Activation.AllowEdit = Enable
Dim index As Integer = e.Row.Index
If e.Row.IsAddRow Then
dgTimeSheet.Rows(index).Cells(PROJECT).Activation = Activation.AllowEdit
dgTimeSheet.Rows(index).Cells(SERVICE_ISSUE_CLASS).Activation = Activation.AllowEdit
dgTimeSheet.Rows(index).Cells(MILESTONE).Activation = Activation.AllowEdit
Else
dgTimeSheet.Rows(index).Cells(PROJECT).Activation = Activation.NoEdit
dgTimeSheet.Rows(index).Cells(SERVICE_ISSUE_CLASS).Activation = Activation.NoEdit
dgTimeSheet.Rows(index).Cells(MILESTONE).Activation = Activation.NoEdit
End If
CheckRows()
End Sub
The problem is that if I click on disabled/read-only rows, then newly added rows also get disabled, which I don't want.
I am fighting with a similar problem in C#, so this is fishing in the dark... Is it possible, in your case, to add an IgnoreRowColActivation = true statement to keep the rows from reverting?
This examples create read only columns for the interface a customer uses
Example for a row with three columns. Set two columns as readonly and the third as editable to the user.
the three columns defined in the designer:
System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
set column 1 & 2 directly
this.dataGridViewTextBoxColumn1.ReadOnly = true
this.dataGridViewTextBoxColumn2.ReadOnly = true
You can still update all columns in the source code. The customer will only be able to edit the third column.
I have the following code:
Dim i As Integer = dtResult.Rows.Count
For i = 0 To dtResult.Rows.Count Step 1
strVerse = blHelper.Highlight(dtResult.Rows(i).ToString, s)
' syntax error here
dtResult.Rows(i) = strVerse
Next
I want to add a strVerse to the current row.
What am I doing wrong?
The problem you're running into is that you're trying to replace an entire row object. That is not allowed by the DataTable API. Instead you have to update the values in the columns of a row object. Or add a new row to the collection.
To update the column of a particular row you can access it by name or index. For instance you could write the following code to update the column "Foo" to be the value strVerse
dtResult.Rows(i)("Foo") = strVerse
You can access columns by index, by name and some other ways:
dtResult.Rows(i)("columnName") = strVerse
You should probably make sure your DataTable has some columns first...
Dim myRow() As Data.DataRow
myRow = dt.Select("MyColumnName = 'SomeColumnTitle'")
myRow(0)("SomeOtherColumnTitle") = strValue
Code above instantiates a DataRow. Where "dt" is a DataTable, you get a row by selecting any column (I know, sounds backwards). Then you can then set the value of whatever row you want (I chose the first row, or "myRow(0)"), for whatever column you want.