Not allow selection of a certain column in a DataGridView control - vb.net

I have this datagridview
I was wondering if there is a way to disable the abillity of the user to select cells of the first column (the one with an arrow), but i still need the user to be able to select all other cells,exept the ones on the first column.

If the selection is moved to the target column, using the DataGridView1.SelectionChanged event you can prevent the selection focus, setting the DataGridView1.CurrentCell to next column cell in the same row.
This works for selection events generated by both Mouse clicks and cursor movement.
Private blockedColumn As Integer = 0
Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) Handles DataGridView1.SelectionChanged
If DataGridView1.CurrentCell.ColumnIndex = blockedColumn Then
DataGridView1.CurrentCell =
DataGridView1(blockedColumn + 1, DataGridView1.CurrentCell.RowIndex)
End If
End Sub
You could set dataGridView1.Columns(0).Frozen = True anyway, for other uses. But it's not necessary.

Related

Focus and enter editing in specific cell in ReadOnly DGV

I'm trying make an option in ContextMenuStrip for my DataGridView which will allow to edit specific cell within the selected row, while the DataGridView is ReadOnly as default.
I have the following code which seems to work for other people, but not for me:
Private Sub Edit_ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles Edit_ToolStripMenuItem.Click
If DGV_1.SelectedRows.Count > 1 Then
MsgBox("Please select only one item.")
Else
DGV_2.CurrentRow.Cells(2).ReadOnly = False
DGV_2.CurrentCell = DGV_2.Item("Qty", DGV_2.CurrentRow.Index)
DGV_2.BeginEdit(True)
End If
End Sub
Bit more context - DGV_2 values are based on selection within DGV_1, hence the If statement to only allow edit row cell Qty in DGV_2 when its values are coming from only 1 selected row in DGV_1.
When this option is clicked, I want the user to be focused/entered into edit mode of the Qty cell within the selected row in DGV_2.
Again, as per #jmcilhinney comments under the initial question, I was able to solve my issue by making DGV_2.ReadOnly = False and then configuring the below event:
Private Sub DGV_2_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles DGV_2.RowsAdded
If DGV_2.Rows.Count > 0 Then
DGV_2.Rows(e.RowIndex).Cells(0).ReadOnly = True
DGV_2.Rows(e.RowIndex).Cells(1).ReadOnly = True
DGV_2.Rows(e.RowIndex).Cells(2).ReadOnly = True
DGV_2.Rows(e.RowIndex).Cells(3).ReadOnly = True
End If
End Sub
Now the code I included in the initial question works.
Thanks again #jmcilhinney!

Prevent user from changing programmatical selection in DataGridView

I have a DataGridView whose rows are selected/unselected based on filters set through other controls. This selection is ment to be only programmatical. How can I prevent user from changing these selections?
I thought of answering by telling you to keep DataGridView1.Enabled = False, which may work as per your need, but you might lose some visual effects(like greyed-out DataGridView).
Setting DataGridView1.ReadOnly = True also won't help.
So the below code is not a perfect solution but more like a workaround to get exactly what you want (tested now & completely working):
Dim SelectedRows As List(Of DataGridViewRow) = New List(Of DataGridViewRow)
Private Sub DataGridView1_MouseDown(sender As Object, e As MouseEventArgs) Handles DataGridView1.MouseDown
For Each Rows As DataGridViewRow In DataGridView1.SelectedRows
SelectedRows.Add(Rows) 'Add all the rows pre-defined by your code
Next
End Sub
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
DataGridView1.ClearSelection() 'clear the selection
For Each rs As DataGridViewRow In SelectedRows
rs.Selected = True 'restore the previous selected rows
Next
End Sub
Private Sub DataGridView1_RowHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.RowHeaderMouseClick
DataGridView1.ClearSelection() 'clear the selection
For Each rs As DataGridViewRow In SelectedRows
rs.Selected = True 'restore the previous selected rows
Next
End Sub
I'm not sure if it is possible (without customizing DataGridView) to keep it enabled (so to see selection) and avoid user to be allowed to select rows.
However, you can store your selection i.e. in a list(of int16) and handle events like CellClick and re-read and reset the selection from the list every time the user clicks inside DataGridView. Hopefully it won't be even noticeable to the user, but either way it will not allow him to modify the selection.

Disable Button If Combox Input Deleted

In my project, I have a few textbox inputs, and some combo boxes with maybe 2 indexed items on a form. There's a button I'm disabling on load if no input is supplied to both textbox inputs, and it works great even if I delete out any text. However, I'm having issues with forcing the combo box to behave in the same manner. This work however:
Private Sub cboPickShirts_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboPickShirts.SelectedIndexChanged
InputCheck_3 = True
If cboPickShirts.SelectedIndex < 0 Then
InputCheck_3 = False
End If
If InputCheck_3 = False Then
btnInputResult.Enabled = False
ElseIf InputCheck_3 = True Then
btnInputResult.Enabled = True
End If
End Sub
I have InputCheck_3 set up as a global variable in a Public Module. On form load, I'm disabling my button and it doesn't enable until I select one of the indexed items. My struggle to get the button disable again if any combo box text is entered and deleted out, leaving it null or empty. Any thoughts on what I'm missing or what I can add to get results? I guess I need a variable or event to notice the change (entering & deletion of text).
The problem you are having is that your SelectedIndexChanged event is not being triggered when you remove the selected item from your ComboBox. I would use the TextChanged event of your TextBox's and ComboBox and give it a common handler and check it that way. Something like this
Private Sub TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged, TextBox2.TextChanged, cboPickShirts.TextChanged
EnableCheck()
End Sub
Private Sub EnableCheck()
btnInputResult.Enabled = (String.IsNullOrEmpty(TextBox1.Text) And String.IsNullOrEmpty(TextBox2.Text) And ComboBox1.SelectedIndex = -1)
End Sub
You can also check that the comboBox is NullorEmpty the same way as the textbox's. As it stands right now the combobox will be enabled when the text no longer matches a selection.
One line code
btnInputResult.Enabled = If((cboPickShirts.SelectedIndex<0),False, True)

vb.net add values from listbox to textbox via drag&drop AND via double click

I'm struggling with some functionality I want to use on my Windows form.
( Just for info, this is for an AutoDesk Inventor AddIn. )
This is my form layout.
The current workflow
The top 4 list-boxes are filled with available parameter names. The user chooses the parameter(s) he/she wants to use and drags and drops it into one of the driving parameter text-boxes ( marked with the <1> label ).
The code that relates to the drag and drop operations
Private Sub lstTemp_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles lbModelParameters.MouseDown,
lbUserParameters.MouseDown,
lbReferenceParameters.MouseDown,
lbLinkedParameters.MouseDown
' In order to access a specific item in a listbox.itemcollection, you must think of it
' as an array of data or a collection and access it in the same manner by always
' letting VB know which item you intend to use by identifying it with its index location
' within the collection. And this is better than taking up basket weaving :-)
lbModelParameters.DoDragDrop(sender.Items(sender.SelectedIndex()).ToString, DragDropEffects.Move)
End Sub
Private Sub txtTemp_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) _
Handles tbParameter1.DragEnter,
tbParameter2.DragEnter,
tbParameter3.DragEnter,
tbParameter4.DragEnter,
tbParameter5.DragEnter
'Check the format of the incoming data and accept it if the destination control is able to handle
' the data format
'Data verification
If e.Data().GetDataPresent(DataFormats.Text) Then
e.Effect() = DragDropEffects.Move
Else
e.Effect() = DragDropEffects.None
End If
End Sub
Private Sub txtTemp_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) _
Handles tbParameter1.DragDrop,
tbParameter2.DragDrop,
tbParameter3.DragDrop,
tbParameter4.DragDrop,
tbParameter5.DragDrop
'This procedure receives the dragged data once it passes the data verification handled by the DragEnter method
'Drops the data onto the destination control
sender.Text() = e.Data().GetData(DataFormats.Text).ToString()
End Sub
New functionality
Now I would like to decrease the user mouse movement for ergonomic reasons and speed. But I would also like to keep to the drag and drop functionality. As it can overwrite a value that has already been added by the user.
I would like to be able to DoubleClick a item in the listbox, and that item should be added to the first empty textbox. I named my textboxes with a number so it's easy to loop over them all to check if it's empty.
I tried doing it with this code, but my double click event never gets fired. It always goes to the drag and drop. How do you do handle this, that the double click gets fired instead of drag drop?
Private Sub ParameterAddDoubleClick(sender As Object, e As EventArgs) _
Handles lbModelParameters.DoubleClick,
lbUserParameters.DoubleClick,
lbReferenceParameters.DoubleClick,
lbLinkedParameters.DoubleClick
Dim oControl As Windows.Forms.ListBox
oControl = DirectCast(sender, Windows.Forms.ListBox)
' Add line in likedparameters listbox
If oControl.SelectedIndex <> -1 Then
' Loop trough all the controls to see if one is empty
' if it's empty add parameter, else go to next
' if all textboxes are used do nothing.
For i = 1 To 6
Dim oTextbox As Windows.Forms.TextBox =
CType(gbDrivingParameters.Controls("tbParameter" & i),
Windows.Forms.TextBox)
If oTextbox.TextLength = 0 Then
' Add the sender item into the linked listbox
oTextbox.Text = oControl.Items.Item(oControl.SelectedIndex)
End If
Next
End If
End Sub
I hope my question is clear, and well prepared. If there is additional information needed, please let me know in a comment.
Mousedown triggers the DoDragDrop, wich stops the doubleclick-event from firing.
To identify if a user doubleclicks or wants to perform a dragdrop, consider the following:
Private Sub ListBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListBox1.MouseDown
' Determine whether we are performing a drag operation OR a double click
If e.Clicks = 1 Then
TextBox1.Text = "mousedown"
Else
TextBox1.Text = "dblclick"
End If
End Sub

how to put search functionality in dataGridView in vb.NET

How can I select a single cell from selected row in datagridView and after selecting that I want to put simple search functionality (like we have in our windows folders-typing any characters and search should work)?
I do not really understand your question. If you want to select one cell, you can use the celldoubleclick event for exemple. And the to get the selected cell, use e.rowindex and e.columnindex which will give you the row and the column where the cell is located.
You can try this as a possible solution.
Dim nwData as CustomersDataSet = CustomersDataSet.GetCustomers()
m_CustomersGrid.DataSource = m_CustomersBindingSource
m_CustomersBindingSource.DataSource = nwData.Customers
Then you can sort using the BindingSource.
CustomersBindingSource.Sort = "ContactName ASC"
And you can find using the BindingSource.
Dim index as integer = _
CustomersBindingSource.Find("CompanyName", CompanyNameTextBox.Text)
If index <-1 then 'it was found; move to that position
CustomersBindingSource.Position = index
End If
You could then populate:
CustomersBindingSource.Find("CompanyName", CompanyNameTextBox.Text)
with the keys pressed in the cell by capturing them by utilizing:
Private Sub DataGridView1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyUp
Dim dgv As DataGridView = TryCast(sender, DataGridView)
If dgv IsNot Nothing Then
'You will need some logic here to determine how long to wait between keyups
'Perhaps a timer that ticks every500 milliseconds and reset on keyup.
e.KeyData
End If
End Sub
I found the original Biding Source Logic at : This Location