Double-click DataGridView row? - vb.net

I am using vb.net and DataGridView on a winform.
When a user double-clicks on a row I want to do something with this row. But how can I know whether user clicked on a row or just anywhere in the grid? If I use DataGridView.CurrentRow then if a row is selected and user clicked anywhere on the grid the current row will show the selected and not where the user clicked (which in this case would be not on a row and I would want to ignore it).

Try the CellMouseDoubleClick event...
Private Sub DataGridView1_CellMouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDoubleClick
If e.RowIndex >= 0 AndAlso e.ColumnIndex >= 0 Then
Dim selectedRow = DataGridView1.Rows(e.RowIndex)
End If
End Sub
This will only fire if the user is actually over a cell in the grid. The If check filters out double clicks on the row selectors and headers.

Use Datagridview DoubleClick Evenet and then Datagrdiview1.selectedrows[0].cell["CellName"] to get value and process.
Below example shows clients record upon double click on selected row.
private void dgvClientsUsage_DoubleClick(object sender, EventArgs e)
{
if (dgvClientsUsage.SelectedRows.Count < 1)
{
MessageBox.Show("Please select a client");
return;
}
else
{
string clientName = dgvClientsUsage.SelectedRows[0].Cells["ClientName"].Value.ToString();
// show selected client Details
ClientDetails clients = new ClientDetails(clientName);
clients.ShowDialog();
}
}

Use DataGridView.HitTest in the double-click handler to find out where the click happened.

I would use the DoubleClick event of the DataGridView. This will at least only fire when the user double clicks in the data grid - you can use the MousePosition to determine what row (if any) the user double clicked on.

You could try something like this.
Private Sub DataGridView1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.DoubleClick
For index As Integer = 0 To DataGridView1.Rows.Count
If DataGridView1.Rows(index).Selected = True Then
'it is selected
Else
'is is not selected
End If
Next
End Sub
Keep in mind i could not test this because i diddent have any data to populate my DataGridView.

You can try this:
Private Sub grdview_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdview.CellDoubleClick
For index As Integer = 0 To grdview.Rows.Count - 1
If e.RowIndex = index AndAlso e.ColumnIndex = 1 AndAlso grdview.Rows(index).Cells(1).Value = "" Then
MsgBox("Double Click Message")
End If
Next
End Sub

Related

Hide rows if column contains particular text/ string

I have a datagridview wich I have no bound datasource too I also have a button and three rows in my datagridview. If my column named STATUS contains the word CLOSED I would like to hide that entire row but i dont want to delete it just hide it.
If anyone woyuld like to know I am ussing VB.net
How can I do this?
If you are using a bound datasource you want to capture the DataGridView.DataSourceChanged event.
Would look like this.
Private Sub DataGridView1_DataSourceChanged(sender As Object, e As System.EventArgs) Handles DataGridView1.DataSourceChanged
For Each row As DataGridViewRow In DirectCast(sender, DataGridView).Rows
If row.Cells("status").Value.ToString.ToLower.Contains("Closed") Then
row.Visible = False
End If
Next
End Sub
If you are not using a datasource you would want to capture the DataGridView.RowsAdded event.
Would look like this.
Private Sub DataGridView1_RowsAdded(sender As Object, e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) Handles DataGridView1.RowsAdded
Dim dg As DataGridView = sender
If dg.Columns.Count > 0 And e.RowIndex <> 0 Then
Dim theRow As DataGridViewRow = dg.Rows(e.RowIndex)
If theRow.Cells("status").Value.ToString.ToLower.Contains("closed") Then
theRow.Visible = False
End If
End If
End Sub

Gridview-Datasource: Datatable loses all its Rows

I've come across a rather strange behavior.
Behind my form i have my constructor which looks like this:
Private Property SourceDatatable As DataTable
Public Sub New()
' This call is required by the designer.
InitializeComponent()
SourceDatatable = GetData()
'SourceDatatable now has 500 rows
AvailableObjects.DataSource = SourceDatatable
End Sub
Right now all 500 rows are visible inside the gridview.
When the user clicks a button, then the selected row is 'copied'
Private Sub CopyObject_Click(sender As System.Object, e As System.EventArgs) Handles AddNewObject.Click
Dim selectedRow As Integer = GridviewAvailableObjects.GetSelectedRows().FirstOrDefault()
If (selectedRow > 0) Then
Dim selectedDataRow As Integer = GridviewAvailableObjects.GetRowHandle(selectedRow)
SelectedRecords.Rows.Add(SourceDatatable.Rows(selectedDataRow))
End If
GridViewSelectedValues.RefreshData()
End Sub
The error occurs at SourceDatatable.Rows(selectedDataRow). All of a sudden it has 0 rows, Yet selectedDataRow refers to the correct row in the datasource(datatable). There is no interference of other Methods/Code as these 2 methods are the only ones present on the form and there is no other code on this form. Nor is the grid or any control accessible from outside the form.
What could cause this strange behavior? Does de Devexpress Gridview do anything with the datasource?
You should not directly add rows from one table to another due to DataTable restrictions - it will throw the System.ArgumentException ("This row already belongs to another table") exception. This issue is not specific to DevExpress GridView. And you can avoid it with easy via copying only "values" from the original row into another table.
This version of "copying" works to me, please review it:
void btnCopy_Click(object sender, EventArgs e) {
var selectedRowHandles = gridViewForAllData.GetSelectedRows();
for(int i = 0; i < selectedRowHandles.Length; i++) {
var selectedRow = gridViewForAllData.GetDataRow(selectedRowHandles[i]);
selectedRowsTable.Rows.Add(selectedRow.ItemArray);
}
gridViewForSelectedValues.RefreshData();
}
VB.Net:
Private Sub btnCopy_Click(ByVal sender As Object, ByVal e As EventArgs) Handles simpleButton1.Click
Dim selectedRowHandles = gridViewForAllData.GetSelectedRows()
For i As Integer = 0 To selectedRowHandles.Length - 1
Dim selectedRow = gridViewForAllData.GetDataRow(selectedRowHandles(i))
selectedRowsTable.Rows.Add(selectedRow.ItemArray)
Next i
gridViewForSelectedValues.RefreshData()
End Sub

How to use IF AND statement with events

I want to do something if both a Listbox Item is selected and a Button is clicked. What I'm thinking is like this but it clearly isn't correct.
If ListBox1.SelectedIndex >= 0 And btnConvert_click Then
(This is under the ListBox1_SelectedIndexChanged Private Sub)
You would need to do something like this
Private sub btnConvert_click (sender as Object, e as EventArgs) Handles btnConvert.Click
If Combo.SelectedIndex > -1 Then ' SelectedIndex= -1 --> nothing selected
' Do your code
End If
End Sub
And in your case you wouldn't use Combo_Selected. This is if you want select the item and click the button. Remember, first item has index "0".

Hide a row in DataGridView

I am a new user to vb.net and need to hide a row when a user right clicks on a contextmenu and selects hide. I have googled this but have yet to find a way to do it.
At the moment, when a user clicks on an entry in the grid, the value is entered into a text box which is fine. What I need to do is hide the entry the user right clicked on and hide the selection. As I am new I am finding it hard going to code this as I have just finished my first course which entailed the basics. Any help would be appreciated or if you need anymore code, then please ask.
Dim value As Object = UserDataGridView.Rows(e.RowIndex).Cells(0).Value
txtCustomerActive.Text = CType(value, String)
Private Sub HideToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles pnlContextMenuStrip1.ItemClicked
'Get the text of the item that was clicked on.
'Dim text As String = txtCustomerActive.Text
Try
'txtCustomerActive.Visible = False
pnlContextMenuStrip1.Visible = False
MessageBox.Show(txtCustomerActive.Text)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
You could use Rows.Item() to hide specific DataGridViewRow, like:
If (UserDataGridView.Rows.Count > 0) Then
For Each row As DataGridViewRow In UserDataGridView.SelectedRows
UserDataGridView.Rows.Item(row.Index).Visible = False
Next
End If
I am assuming you are using FullRowSelect here.
If you are not using FullRowSelect you could have this alternative code which could catch both Cell being Selected or Row being Selected:
If (UserDataGridView.SelectedRows.Count > 0) Then
For Each row As DataGridViewRow In UserDataGridView.SelectedRows
UserDataGridView.Rows.Item(row.Index).Visible = False
Next
ElseIf (UserDataGridView.SelectedCells.Count > 0) Then
For Each cell As DataGridViewTextBoxCell In UserDataGridView.SelectedCells
UserDataGridView.Rows.Item(cell.RowIndex).Visible = False
Next
End If
To Unhide everything let's say from a Button Click you could have this:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
For Each row As DataGridViewRow In UserDataGridView.Rows
If (row.Visible = False) Then
UserDataGridView.Rows.Item(row.Index).Visible = True
End If
Next
End Sub
As far as I know, you can not make a server-side handler for right mouse click (as you did for HideToolStripMenuItem_Click, which works as part of .NET postback mechanism).
However, I believe that such feature could be done with some client-side javascript progamming.
Hope this helps!

Getting row number in a DataGridView

How do you get row number DataGridView cell? Specifically, if a user has selected a single cell, how can you get that row number? It needs to access a particular cell based on what the user has selected.
I know that the RemoveAt method can be used to remove at the Focus, but you cannot get the row number at focus apparently?
Thanks for the help!
You can simply use RowIndex on the current cell:
var row = dataGridView1.CurrentCell.RowIndex;
this one works fine .
Private Sub DataGridView1_RowPrePaint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewRowPrePaintEventArgs) Handles DataGridView1.RowPrePaint
If e.RowIndex >= 0 Then
Me.DataGridView1.Rows(e.RowIndex).Cells(0).Value = e.RowIndex + 1
End If
End Sub
It is nearly the same but you may also use this solution:
var row = dataGridView1.CurrentRow.Index
Another way if you need to track user interaction with a DataGridView:
In my case there is extra processing in some generic functions that use the Me.I_SelCol and Me.I_SelRow column and row coordinates, but I haven't shown that because it's not relevant to the OP.
Best regards,
Rob
Private Sub I_DataGridView_CurrentCellChanged(sender As Object, e As EventArgs) Handles I_DataGridView.CurrentCellChanged
If Me.I_DataGridView.CurrentCellAddress.X < 0 Or Me.I_DataGridView.CurrentCellAddress.Y < 0 Then Exit Sub
' The Windows Me.I_DataGridView object will have already deselected the current cell and selected the
' new cell as per user navigation using mouse or cursor keys. We just need to store the current
' co-ordinates for the currently selected cell.
Me.I_SelCol = Me.I_DataGridView.CurrentCellAddress.X
Me.I_SelRow = Me.I_DataGridView.CurrentCellAddress.Y
Exit Sub
If you in event procedure of datagridview you will found "e As DataGridViewCellEventArgs" you can get row number with e.RowIndex and column number with e.ColumnIndex
Private Sub myDGV_CellLeave(sender As Object, e As DataGridViewCellEventArgs) Handles myDGV.CellLeave
Dim myRow As Integer = e.RowIndex
End Sub
And if you in normal procedure you can get row number like this:
Private Sub btnGetRow_Click(sender As Object, e As EventArgs) Handles btnGetRow.Click
dim myRow1 as Integer = 0
dim myRow2 as Integer = 0
myRow1 = myDGV.CurrentCell.RowIndex
myRow2 = myDGV.CurrentRow.Index
End Sub