Cannot delete datagridview rows after programmatically selecting them - vb.net

Hi I have a datagridview in virtual mode.
Using this code I select multiple rows if they contain a certain string:
Try
For Each row As DataGridViewRow In DataGridView1.Rows
If row.Cells(1).Value.ToString().Contains(TextBox1.Text) Then
DataGridView1.Rows(row.Index).Selected = True
End If
Next
Catch
End Try
This code works to select the rows, but then I am unable to delete any of them using the DEL key. It's almost like the rows have not fired that they are actually selected. If I ctrl-click another row that was not part of the selection group, I can then delete all the selected rows. Does this control click fire come sort of update letting the grid know what rows are selected? How can I solve this issue?

Seems as if it was a really silly issue. I solved it by just setting focus back to the datagrid using:
DataGridView1.Focus()

I was able to reproduce the issue. I see that if you just hit the delete key after programmatically selecting the rows for the user on certain conditions the rows will not delete. I think ("not sure") because it doesn't know where you clicked the delete key. If you were to do something like the below, it would delete the selected records.
Private Sub Form1_keypressed(sender As System.Object, e As System.EventArgs) Handles MyBase.KeyDown
If Keys.E + Keys.Delete Then
For Each rows As DataGridViewRow In DataGridView1.SelectedRows
DataGridView1.Rows.Remove(rows)
Next
End If
End Sub

Related

how to delete record from persisted store when user deletes row in Datagridview

I am currently using this:
Private Sub PersonDataGridView_UserDeletingRow(sender As Object, e As DataGridViewRowCancelEventArgs) Handles PersonDataGridView.UserDeletingRow
DBContext.Persons.Remove(e.Row.DataBoundItem)
End Sub
But this behaves strange: it sometimes deletes the right record, but then gives an error about index out of range (translated from Dutch: error in Datagridview: index out of range: ThrowArgumentOutOfRangeException) afterwards;
Example: I have 5 rows in the datagridview; I delete row 3 using the above code, then rows 3 and 4 are removed from the datagridview. This causes an error when trying to save the DBcontext on that second deleted row, because it has not been set to "deleted" in the context...
You want to use UserDeletedRow. Using the UserDeletingRow, you are deleting record 3 from the data source as you want, but then the datagridview changes and it will fire the userdeletingrow again.
You want to perform the delete in the data source only after the record has been deleted from the gridview.

Get the actual value of a BoundField element in a gridview VB.NET

The following image depicts the full gridview I have:
I'm able to get the values of the second column (project_ID) in the back end as follows:
Dim val As String = grdProjects.SelectedRow.Cells(1).Text.ToString
For instance if I press the Select of the third row I'll get back the value 3.
My problem appears when the gridview is updated and has less records as the one in the following image.
If I press the second record I get the value 2 instead of the value 4 that I'd like to get.
Any suggestions please on how to get the actual value of the cell instead of the number of the selected row?
I might be wrong but in VB.net datagrids SelectedRow does not exist, SelectedRows do exist.
Anyway, try this way and let me know if it work:
On the RowEnter or CellClick event use the E.RowIndex to get what you want. Do as follow:
Private Sub DataGrid1_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles DataGrid1.RowEnter
Dim CellValue As String = DataGrid1.Rows(e.RowIndex).Cells("Project_ID").Value.ToString
End Sub
Notice that for the .cells() I use the name of the column, this is better because if in the future you add columns this code will not need to be changed. Easier code maintenance always pay! Also. Cell().Value instead Cell().Text
Nandostyle

DataGridView check all Rows vb.net

Private Sub comboBoxStudentID_SelectedIndexChanged(sender As Object, e As EventArgs) Handles comboBoxStudentID.SelectedIndexChanged
For Each dr As DataGridViewRow In Me.dataGridViewStudent.Rows
If dr.Cells(0).Value.ToString.Contains(comboBoxStudentID.Text) Then dr.Visible = True Else dr.Visible = False
Next
End Sub
I've created this method to check and display a row that contains the same Student ID as selected from the comboBoxStudentID the problem is it only checks the first row of the DataGridView. How can I make it check all of the rows if there is match of Student ID?
Without knowing how your data is organized, you could do this by binding the DataGridView and the ComboBox to the same data source. Since this is not specified and looking at the snippet of code (which appears to work) it appears to loop through the rows and if the currently selected combo box text is contained in the first column cell, then make that row visible. Otherwise make the row invisible.
The posted code appears to work however there is one scenario you may want to consider. If the combo box contains the values that are in column one of the DataGridView, THEN, when the user selects a value in the combo box, the DataGridView will display ONLY those values that match the current combo box selection. This appears to be what you are trying to do.
The problem is how do you re-display all the rows?
Once the combo box selection has changed to some value, the user can delete the selection but all the rows will not display unless you handle another event. Also this strategy is not very user intuitive. One possible solution (below) simply adds a top item of “Reset” to the top of the combo boxes items. Then when the user selects “Reset” all row will become visible. Hope this helps.
To reiterate: you should consider setting this up with a DataSource and possibly a BindingSource where this is done for you automatically. Just a thought.
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
If ComboBox1.SelectedIndex > 0 Then
For Each dr As DataGridViewRow In DataGridView1.Rows
If (Not dr.IsNewRow) Then
If dr.Cells(0).Value.ToString.Contains(ComboBox1.Text) Then
dr.Visible = True
Else
dr.Visible = False
End If
End If
Next
Else
For Each row As DataGridViewRow In DataGridView1.Rows
row.Visible = True
Next
End If
End Sub

VB Datagridview cellvalidating event to check if active cell is empty berore leaving problems

In Visual basic i'm trying to make a field required by preventing the user to leave the active cell if it's empty.
The grid consists out of two columns. The first one is the ID which is automaticly filled in on adding a new row, the second one is the name.
On form load there are 4 items loaded into the grid. When the form is loaded the first cell that is selected passes the check with no problem. It is the same for the three cells that are filled on form load.
Unforunately it does not seem to work when i try to add a new row to the grid, enter a value and try to leave the cell. I've set a break point and checked the values. The value is equal to nothing... This is not the case with any of the already loaded values.
How does it not get the value i enter?
Thanks in advance.
Ivan.f
Private Sub ValidateCellValue(sender As Object, e As
DataGridViewCellValidatingEventArgs)
Handles grdResult.CellValidating
Dim catNaam = grdResult.Rows(e.RowIndex).Cells(1).Value
If IsNothing(catNaam) Then
MessageBox.Show("Veld mag niet leeg zijn")
e.Cancel = True
Exit Sub
End If
End Sub

VB.NET Listview Textchanged Search

I've tried searching on stackoverflow and implementing code that I found but to no avail. As the text changes I want to use the current text in the textbox to filter through the listview items (so the items that are not closed to being matched get removed) and it only leaves me with whatever is contained in the columns.
Here's an example of what I mean:
Search: "Georges"
|1|Anderson Silva|Anderson silva is the champion in the ...|
|2|Georges St-Pierre| Georges is the champion in the ...|
|3|Georges Sotoropolis| Georges Sotoropolis is a fighter in the lightweight division|
With this search, only rows 2 and three would be returned. The first row would be omitted and not displayed. Once I erase the terms, then it would get displayed.
Here is the code that I currently have:
Private Sub tbSearch_TextChanged(sender As Object, e As System.EventArgs) Handles tbSearch.TextChanged
lwArticles.BeginUpdate()
If tbSearch.Text.Trim().Length = 0 Then
'Clear listview
lwArticles.Clear()
'If nothing is in the textbox make all items appear
For Each item In originalListItems
lwArticles.Items.Add(item)
Next
Else
'Clear listview
lwArticles.Clear()
'Go through each item in the original list and only add the ones which contain the search text
For Each item In originalListItems
If item.Text.Contains(tbSearch.Text) Then
lwArticles.Items.Add(item)
End If
Next
End If
lwArticles.EndUpdate()
End Sub
It seems to be working but I cannot see the listview items once I enter something in the tbSearch. The scrollbar gets smaller / larger depending if there are more / less items due to the search being executed. My problem seems that they are not visible
Thank you!
Listview.Clear wipes out the items, columns, and groups. It appears you only want to wipe out the items, so call lwArticles.Items.Clear instead of lwArticles.Clear
I would suggest another approach - first create a DataTable based on your original items. Then create a DataView and assign that as DataSource of your ListView. Now you can change DataView.RowFilter, and your list will update automatically, so only items matching the filter will show up. Using this approach you don't need to recreate everything from scratch every time, and your TextChanged becomes very simple and maintainable - it just changes RowFilter, if a corresponding DataView has already been created.
Here's the final answer of my question:
Private originalListItems As New List(Of ListViewItem) 'this gets populated on form load
Private Sub tbSearch_TextChanged(sender As Object, e As System.EventArgs) Handles tbSearch.TextChanged
lwArticles.BeginUpdate()
If tbSearch.Text.Trim().Length = 0 Then
'Clear listview
lwArticles.Items.Clear()
'If nothing is in the textbox make all items appear
For Each item In originalListItems
lwArticles.Items.Add(item)
Next
Else
'Clear listview
lwArticles.Items.Clear()
'Go through each item in the original list and only add the ones which contain the search text
For Each item In originalListItems
If item.Text.Contains(tbSearch.Text) Then
lwArticles.Items.Add(item)
End If
Next
End If
lwArticles.EndUpdate()
End Sub
Credits to Dan-o for explaining that lwArticles.Clear() will clear everything. He notified me that I needed lwArticles.Items.Clear() to clear only the items in the listview.