Datagridview: How to change color of alternate rows having cell value alternate days? - vb.net

Respected Sir,
I have a datagridview filled with data having various timestamps in one column
And trying to colour rows in range of alternate days like the image above. So far, i am trying like this
Private Sub alternateDaysRows()
For i As Integer = 1 To Me.datagridview1.Rows.Count - 1
If i > 1 Then
Dim myLastRowDate As Date
myLastRowDate = CType(Me.datagridview1.Rows(Me.datagridview1.Rows.Count - 1).Cells(2).Value, DateTime).Date
myCountDate = myLastRowDate.AddDays(1)
For Each row As DataGridViewRow In Me.datagridview1.Rows
If CType(row.Cells(2).Value, DateTime).Date = myCountDate Then
row.DefaultCellStyle.BackColor = Color.WhiteSmoke
End If
Next
End If
Next
End Sub
any suggestions ?
yours faithfully
Murulimadhav

Something along these lines may do what you want:
Private Sub alternateDaysRows()
Dim myLastRow As DataGridViewRow = Nothing
Dim myLastColor = Color.Yellow
Dim isFirstRow As Boolean = True
For Each row As DataGridViewRow In Me.DataGridView1.Rows
If myLastRow IsNot Nothing Then
If DateTime.Parse(myLastRow.Cells(0).Value.ToString).Date <> DateTime.Parse(row.Cells(0).Value.ToString).Date Then
myLastColor = If(myLastColor = Color.Yellow, Color.Red, Color.Yellow)
End If
End If
myLastRow = row
row.DefaultCellStyle.BackColor = myLastColor
Next
This assumes that the cells are sorted in date order and that the values are convertable to a date. It alternates when the date changes rather than on every other day but would highlight when a different day is being viewed.

Related

prevent go to next row when duplicated value in `datagridview`

I have datagrid that user will add values in just one column , and i want to prevent duplicated data in this column, i had mange that by the code bellow,
what I want is to keep the selection (focus) in the same editing cell(x)
if the entered data is duplicated, so I tried to get the current row index and return to it if the data is duplicated but its not working.
row_index = DataGridView1.CurrentRow.Index.ToString()
Dim cell As DataGridViewCell = DataGridView1.Rows(row_index).Cells(1)
DataGridView1.CurrentCell = cell
DataGridView1.BeginEdit(True)
NOTE : User will Add barcode number, so he will use barcode scanner or add it manually and press enter key.
Private Sub DataGridView1_RowValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.RowValidated
If DataGridView1.Rows.Count > 2 Then
Dim i As Integer = 0
Dim row_index As Integer
' loop condition will loop while the row count is less or equal to i
While i <= DataGridView1.Rows.Count - 1
Dim j As Integer = 1
' loop condition will loop while the row count is less or equal to j
While j <= DataGridView1.Rows.Count - 1
Dim str As String = DataGridView1.Rows(i).Cells(1).Value()
Dim str1 As String = DataGridView1.Rows(j).Cells(1).Value()
If Not str1 = "" AndAlso Not str = "" Then
If str1 = str Then
'row_index = DataGridView1.SelectedCells.Item(i).RowIndex.ToString()
row_index = DataGridView1.CurrentRow.Index.ToString()
Dim cell As DataGridViewCell = DataGridView1.Rows(row_index).Cells(1)
DataGridView1.CurrentCell = cell
DataGridView1.BeginEdit(True)
Exit Sub
End If
End If
j += 1
End While
i += 1
End While
End If
End Sub
You can try it also in a for loop. This is how I do it. If what you mean is to stop/retain the selection(focus) or go to in a cell/row whenever it is a duplicate with the current data you have. This should work fine.
enter code here
For i = 0 To Datagridview1.Rows.Count - 1
If Datagridview1.Rows(i).Cells(1).Value = DataYouWillInput Then
DataGridView1.CurrentCell = DataGridView1.Rows(i).Cells(1)
Exit for
End If
Next
enter code here
If your condition returns true with the condition of current data and data you'll be adding. Just exit your loop. Use this.
DataGridView1.CurrentCell = DataGridView1.Rows(i).Cells(1)

Search using textbox VB

I need to search DataGridView by date. If I enter 2/11/2017 in text box, I want grid to show me rows that contain this date. Date column in my DataGridView is named AppointmentDate and is created in SQL Server. Type of this column is only date.
I saw this, but I am using Entity Framework model, I don't know how to realize it.
dgvPacientet.CurrentCell = Nothing
Dim found As Boolean = False
For Each row As DataGridViewRow In dgvPacientet.Rows
row.Visible = row.Cells("Dt_terminit").Value = txtData.Text
If row.Visible Then found = True
Next
If Not found Then MsgBox("Item not found")`
Simply show or hide the rows that contain the text you want.
DataGridView1.CurrentCell = Nothing
Dim found as Boolean = false
For Each row As DataGridViewRow In DataGridView1.Rows
Row.Visible = Not IsDBNull(row.Cells("DT_Terminit").Value) andalso row.Cells("DT_Terminit").Value = TextBox5.Text
If Row.Visible then found = true
Next
If Not found Then MsgBox("Item not found")
However you really need to parse that textbox to make sure it is a date first and if that cell contains a true Date, you need to convert the test into a date.
Dim DT As Date
If Not Date.TryParse(TextBox5.Text, DT) Then
MsgBox("Please enter a date") '<-- remove this line if searching on the fly... (as you enter text)
Exit Sub
End If
DataGridView1.CurrentCell = Nothing
Dim found As Boolean = False
For Each row As DataGridViewRow In DataGridView1.Rows
Row.Visible = Not IsDBNull(row.Cells("DT_Terminit").Value) andalso row.Cells("DT_Terminit").Value =DT
If row.Visible Then found = True
Next
If Not found Then MsgBox("Item not found")

How to compare DataGridView cell data to DataSet cell data

In a VB.NET WinForms project I'm working on in VS2013 I am detecting when the user changes something in a cell on the CellValueChanged event. When a row in the DataGridView is found that is different from the DataSet I highlight the row in pink.
In my code though, I only know how to iterate through all of the rows, rather than just compare the row that fired the CellValueChanged event to the DataSet.
Here's my current code:
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource(e.RowIndex, e.ColumnIndex)
End Sub
Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer)
' Force ending Edit mode so the last edited value is committed
EmployeesBindingSource.EndEdit()
Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanged Is Nothing Then
For Each dt As DataTable In dsChanged.Tables
For Each row As DataRow In dt.Rows
For i As Integer = 0 To dt.Columns.Count - 1
Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor
If Not row(i, DataRowVersion.Current).Equals(row(i, DataRowVersion.Original)) Then
Console.WriteLine("Row index: " & dt.Rows.IndexOf(row))
' This works
dgvEmployees.Rows(rowIndex).DefaultCellStyle.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
Next
Next
End If
End Sub
As you can see, I'm passing the row and column index of the changed cell, so how can I take that and compare it to the specific row and/or cell in the unchanged DataSet?
UPDATE
Nocturnal reminded me that I need to allow for sorting of the DGV, so using row indexes won't work. He offered this as a solution (changed slightly to work with my objects):
If Not dsChanged Is Nothing Then
For Each dtrow As DataRow In dsChanged.Tables("employees").Rows
If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
For i As Integer = 0 To dsChanged.Tables("employees").Columns.Count - 1
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
End If
Next
End If
However, I'm getting an error on the If DirectCast... line saying "Column named "employeeID" cannot be found." I'm not sure if the error is on the DataSet or on the DGV, but there is an employeeID column in the database and DataSet. There is an employeeID as a bound column for the DataGridView, but it is set to Visible = False. That's the only thing I can think of that could possibly cause that error, but if it's a bound column, I would think it could be compared against as in this case.
FINAL WORKING VERSION
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource("employees", e.RowIndex, e.ColumnIndex)
End Sub
Private Sub CompareDgvToDataSource(ByVal dataSetName As String, ByVal rowIndex As Integer, ByVal columnIndex As Integer)
' Takes a dataset and the row and column indexes, checks if the row is different from the DataSet and colors the row appropriately
EmployeesBindingSource.EndEdit()
Dim dsChanges As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanges Is Nothing Then
For Each dtrow As DataRow In dsChanges.Tables("employees").Rows
If DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID.ToString = dgvEmployees.Rows(rowIndex).Cells("employeeID").Value.ToString Then
For i As Integer = 0 To dsChanges.Tables("employees").Columns.Count - 1
If dtrow.RowState.ToString = DataRowState.Added.ToString Then
' TODO: Color entire new row
ElseIf dsChanges.Tables(dataSetName).Rows(0).HasVersion(DataRowVersion.Original) Then
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.employeesRow).employeeID)
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' TODO: Need to change the BackColor back to what it should be based on its original alternating row color
End If
End If
Next
End If
Next
End If
End Sub
My project has four DGVs in it, so this will eventually be expanded to allow for all four DGVs to be checked for changes.
have a look at this approach it is simlar but only iterating the specific Table
Private Sub dgvEmployees_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellValueChanged
' Pass the row and cell indexes to the method so we can change the color of the edited row
CompareDgvToDataSource(e.RowIndex, e.ColumnIndex, sender.DataSource.datamember.ToString)
End Sub
and comparing the ID of the given Table
Private Sub CompareDgvToDataSource(ByVal rowIndex As Integer, ByVal columnIndex As Integer, tablename As String)
EmployeesBindingSource.EndEdit()
Dim dsChanged As DataSet = EmployeesDataSet.GetChanges()
If Not dsChanged Is Nothing Then
For Each dtrow As DataRow In dsChanged.Tables(tablename).Rows
If DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID = dgvEmployees.Rows(rowIndex).Cells("EmployeeID").Value Then
Dim currentColor As System.Drawing.Color = dgvEmployees.AlternatingRowsDefaultCellStyle.BackColor
For i As Integer = 0 To dsChanged.Tables(tablename).Columns.Count - 1
If Not dtrow(i, DataRowVersion.Current).Equals(dtrow(i, DataRowVersion.Original)) Then
Console.WriteLine("Employees ID: " & DirectCast(dtrow, EmployeesDataSet.EmployeeRow).EmployeeID)
' This works
dgvEmployees.Rows(rowIndex).Cells(columnIndex).Style.BackColor = Color.LightPink
Else
' Need to change the BackColor back to what it should be based on its original alternating row color
End If
Next
End If
Next
End If
End Sub
and i am only changing the backcolor of the cell that was changed not the entire row....but depends how you would use that information anyways
EDIT:
with
Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Original).ToString())
Console.WriteLine(EmployeesDataSet.Employee(rowIndex)(columnIndex, DataRowVersion.Current).ToString())
you can see Current and Original Values
123456

Search DataGridView for Integer Then Select Row

The below code should search DataGridView1 which is on the LeaderAccessTable form for an integer that the user inputs into SendFromID, if the DataGridView1's first column contains what the integer that the user has entered into SendFromID then the entire row should be selected. However it doesn't select any rows at all... Can anyone see why? This code is ran from a separate form.
Dim intcount As Integer
For Each Row As DataGridViewRow In LeadersAccessTable.DataGridView1.Rows
If LeadersAccessTable.DataGridView1.Rows(intcount).Cells(0).Value.ToString = SendFromID.Text Then
LeadersAccessTable.DataGridView1.Rows(intcount).Selected = True
End If
Next
MsgBox("Done.")
In the end this code worked.
Dim v_SelectRow As Integer
For counter = 0 To (LeadersAccessTable.DataGridView1.Rows.Count - 1)
For counter2 = 0 To (LeadersAccessTable.DataGridView1.Columns.Count - 1)
If (LeadersAccessTable.DataGridView1.Rows(counter).Cells(0).Value.ToString.Contains(SendFromID.Text)) Then
LeadersAccessTable.DataGridView1.Rows(counter).Cells(0).Selected = True
v_SelectRow = LeadersAccessTable.DataGridView1.CurrentRow.Index
CurrentPoints.Text = LeadersAccessTable.DataGridView1.Item(8, v_SelectRow).Value
'Do Something
Else
'Do Something
End If
Next
Next

VB.NET DataGridView rows

NET Hi I'm new in VB NET and I'm trying to check if all values in the same row of a datagridview are the same.
Exemple :
For Each row In DataGridView1.Rows
If 'all values in row are not the same' Then
row.DefaultCellStyle.BackColor = Color.Red
End if
Next
Tell me if there is anything that you don't understand in my question ^^
Thank you in advance for your help! :P
May be better if you use handler of .RowPrepaint
private sub datagridivew_RowPrepaint(sender as Object, e as DataGridViewRowPrePaintEventArgs) Handles datagridview.RowPrePaint
if e.RowIndex >= 0 then
Dim dgvr as DataGridViewRow = DirectCast(sender, DataGridView).Rows(e.RowIndex)
if IsAllValuesAreSame(dgvr) = True Then
dgvr.DefaultCellStyle.BackColor = Color.Red
End If
End If
End Sub
Then you don't need to loop all rows one more time after all rows initialized.
And function for checking all values of row:
private function IsAllValuesAreSame(dgvr as DataGridViewRow) as Boolean
Dim distinctQnt As Int32 = (From cell As DataGridViewCell In dgvr.Cells
Where cell.ColumnIndex >= 0
Select cell.Value).Distinct().Count()
Return (distinctQnt = 1)
End Function
You need to match the value of all the cells in each row with one cell in that row to know if all cells in that row have the same value. Below, I'm giving you the simplest method to do it and I am choosing the value of the first column of each row to verify if the values of other columns in that row are equal to it. If all the columns/cells of a row don't have the same value, then that row's back color will turn red.
For x = 0 To DataGridView1.RowCount - 1
For y = 0 To DataGridView1.ColumnCount - 1
If DataGridView1.Item(y, x).Value = DataGridView1.Item(0, x).Value Then
'yes
Else
'no
DataGridView1.Rows.Item(x).DefaultCellStyle.BackColor = Color.Red
End If
Next
Next