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
Related
This one is really kicking my butt, i'm hoping someone can point me in the right direction.
I have a combobox on my form that i need to display a "yes" and a "no" instead of a "0" and "1" BUT to process a "0" and "1" depending on the selection. Make sense?
I have the 0 and 1 sitting in the Data > Items > Collection properties of the combobox.
I have tried playing around with the DisplayMember property and the ValueMember property but i cant seem to get these working.
Any ideas would be much appreciated!
In your Data > Items > Collection properties of the combobox
Delete every line in there and add the following, (in the same order)
NO
YES
Now double click on your combobox in the form in design mode.
In the event subroutine for the combobox - selected index changed event, add the following:
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
UserChoseReloadSurvey = ComboBox1.SelectedIndex
End Sub
And that will save either a 1 or 0 in a variable named UserChoseReloadSurvey.
Taking it for granted that you have an integer variable named UserChoseReloadSurvey
By default, a DataGridView is set to EditOnKeystrokeOrF2 edit mode. This means two or three clicks (spaced further apart than the user's double click interval) are required to change the value of a combobox in this view. As this is rather strange for a UI object, you would tend to think the control doesn't work.
Fortunately, you can change the selection mode to EditOnEnter. This will immediately select a cell when clicking on it, not first select the row, reducing the amount of clicks by 1. However, DataGridViews are implemented somewhat strangely. There is a '-1th' cell that is not manually selectable in each row.
When this '-1th' cell is selected, in the normal selection mode the row is selected, but in the "EditOnEnter" mode the 1st cell in the row is selected instead. If the DataGridView is set to enable row deletion using the "Del" key, then using EditOnEnter makes it impossible to use this functionality.
How do I get both to work? I.e.: I don't have a view where the user can have click up to 6 times (users tend to click more rapidly when they have to do so a lot of times) to open a box, while at the same time allowing row selection using the special -1th column?
One would need to programmatically toggle between both edit modes when any cell in the row is clicked. However, the CellClick event fires too late: after the row is already selected. Naively just toggling the EditMode would mean that the first click on the row selection box doesn't work, while the second would, which would appear as buggy behaviour.
The trick is to do much more manually. The following event handler, when attached to the CellClick event, will resolve almost all issues.
Private Sub CellSelect(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles myDataGridView.CellClick
Dim dgv As DataGridView = CType(sender, DataGridView)
If dgv.Rows.Count = 0 Then
Return
End If
Dim rowToSelect As Integer = e.RowIndex
Dim columnToSelect As Integer = e.ColumnIndex
If e.RowIndex = -1 Then
rowToSelect = 0
End If
If rowToSelect >= dgv.Rows.Count Then
rowToSelect = 0
End If
If columnToSelect = -1 Then
dgv.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
dgv.CurrentCell = Nothing
dgv.Rows(rowToSelect).Selected = True
Else
If columnToSelect >= dgv.Rows(rowToSelect).Cells.Count Then
columnToSelect = 0
End If
dgv.EditMode = DataGridViewEditMode.EditOnEnter
dgv.SelectionMode = DataGridViewSelectionMode.CellSelect
dgv.Rows(rowToSelect).Cells(columnToSelect).Selected = True
End If
End Sub
It works by unsetting the selected cell, then setting the selected row programmatically. As the EditMode was changed beforehand, it will select the entire row, not just the first cell, even the first time that the row-selection box is clicked.
There are also a whole bunch of edge cases where a user that clicks quickly enough can create click events on cells that do not exist. So we assume those clicks are on the cell [0,0] so at least our application won't blow up.
This isn't a perfect solution (yet). With this solution: A small graphical glitch remains; for about one frame the DataGridView will flicker between edit modes, very briefly appearing as though the row is selected.
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
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
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.