VB.Net DatagridviewComboBoxColumn CellClick behavior - vb.net

I have a DatagridviewComboBoxColumn populated from a DataTable and whenever I click on any part of the DataGridViewComboBoxCell the first value of the list shows up as it had been clicked. However, when I move the focus to another cell without selecting a value, it disappears.
Strangely, the behavior is not consistent if I apply the ComboBox values with .Items.Add(" "). Can anyone shed some light on this issue.
Here is a sample code and a gif image:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.Rows.Add()
DataGridView1.Rows.Add()
''DataGridViewComboBoxColumn1
DataGridViewComboBoxColumn1.Items.Add("Name1")
DataGridViewComboBoxColumn1.Items.Add("Name2")
'DataGridViewComboBoxColumn2
Dim dt As New DataTable
dt.Columns.Add("id")
dt.Columns.Add("name")
dt.Rows.Add("1", "Name1")
dt.Rows.Add("2", "Name2")
With DataGridViewComboBoxColumn2
.ValueMember = dt.Columns(0).ColumnName
.DisplayMember = dt.Columns(1).ColumnName
.DataSource = dt
End With
End Sub
End Class

Successfully replicated the behavior, but i also added 2 ComboBox to the same form and the result is same
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
DataGridView1.Rows.Add()
DataGridView1.Rows.Add()
''DataGridViewComboBoxColumn1
DataGridViewComboBoxColumn1.Items.Add("Name1")
DataGridViewComboBoxColumn1.Items.Add("Name2")
'DataGridViewComboBoxColumn2
Dim dt As New DataTable
dt.Columns.Add("id")
dt.Columns.Add("name")
dt.Rows.Add("1", "Name1")
dt.Rows.Add("2", "Name2")
With DataGridViewComboBoxColumn2
.ValueMember = dt.Columns(0).ColumnName
.DisplayMember = dt.Columns(1).ColumnName
.DataSource = dt
End With
ComboBox1.Items.Add("Name1")
ComboBox1.Items.Add("Name2")
With ComboBox2
.ValueMember = dt.Columns(0).ColumnName
.DisplayMember = dt.Columns(1).ColumnName
.DataSource = dt
End With
End Sub
End Class
Click to see gif of form in action

I found a way to correct the behavior by referring to this post:
DataGridComboBoxColumn shows first value on CellEnter
Here is the code I have used:
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
If TypeOf e.Control Is ComboBox Then
Dim comboBox As ComboBox = DirectCast(e.Control, ComboBox)
If DataGridView1.CurrentCell.Value Is Nothing Then comboBox.SelectedIndex = -1
End If
End Sub

Related

how combobox autocomplete when selected and then press enter keyboard then fill datagridview

Dear All Master,
how combobox autocomplete when selected and then press enter keyboard then fill datagridview.
I tried typing in combobox then it appeared autocomplete then I selected it and tried to press Enter on the keyboard but the fill datagridView did not appear whether there was something wrong with my code. Please Recommend.
Thanks
Private Sub PopulateComboBox()
Dim query As String = "SELECT DISTINCT PNM FROM GSDTS UNION SELECT DISTINCT PNM FROM GSGTS ORDER BY PNM"
Try
Using con As OleDbConnection = New OleDbConnection(cn)
Using sda As OleDbDataAdapter = New OleDbDataAdapter(query, con)
'Fill the DataTable with records from Table.
Dim dt As DataTable = New DataTable()
sda.Fill(dt)
'Insert the Default Item to DataTable.
Dim row As DataRow = dt.NewRow()
row(0) = ""
dt.Rows.InsertAt(row, 0)
Dim PNM As IList(Of String) = New List(Of String)
For Each _row As DataRow In dt.Rows
PNM.Add(_row("PNM"))
Next
Me.ComboBox1.Items.AddRange(PNM.ToArray)
Me.ComboBox1.AutoCompleteMode = AutoCompleteMode.Suggest
Me.ComboBox1.AutoCompleteSource = AutoCompleteSource.ListItems
'Assign DataTable as DataSource.
ComboBox1.DataSource = dt
ComboBox1.DisplayMember = "PNM"
ComboBox1.ValueMember = "PNM"
End Using
End Using
Catch myerror As OleDbException
MessageBox.Show("Error: " & myerror.Message)
Finally
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.PopulateComboBox()
fillDataGridView1()
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted
fillDataGridView1()
End Sub
You have to handle an event for the combobox. The KeyDown event is automatically called when an item is selected. So you can do this for both selection and pressing the Enter key.
Private Sub ComboBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBox1.KeyDown
If e.KeyCode = Keys.Enter And ComboBox1.Text.Length > 0 Then
MessageBox.Show($"You selected {ComboBox1.Text}")
End If
End Sub

Auto-complete text in the datagridview for single column only

I tried to provide auto-complete text in datagridview. But, I got auto-complete text in all column and after clicking on third column (with combobox) application start displaying error on editing other cells.
I want auto-complete text box in first column i.e. "Name" only. I cannot manage code so that auto-complete doesn't show in second column i.e. "Age" and also error not occurred after clicking on combobox column.
The code is As follow.
Public Class Form1
Private Sub appData(ByVal data As AutoCompleteStringCollection, ByVal c As String)
data.Add("Ravi")
data.Add("Raj")
data.Add("Raja")
data.Add("r " & c)
End Sub
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
Try
MsgBox(e.Control.ToString)
Dim header As String = DataGridView1.Columns(0).HeaderText
If TypeOf e.Control Is TextBox AndAlso header.Equals("Name") AndAlso DataGridView1.CurrentCell.ColumnIndex = 0 Then
If DataGridView1.CurrentCell.ColumnIndex = 0 Then
Dim text As TextBox = TryCast(e.Control, TextBox)
If text IsNot Nothing Then
text.AutoCompleteMode = AutoCompleteMode.Suggest
text.AutoCompleteSource = AutoCompleteSource.CustomSource
Dim data As AutoCompleteStringCollection = New AutoCompleteStringCollection()
appData(data, DataGridView1.CurrentCellAddress.ToString)
text.AutoCompleteCustomSource = data
End If
Else
Dim text As TextBox = TryCast(e.Control, TextBox)
text.AutoCompleteCustomSource = Nothing
text.AutoCompleteSource = AutoCompleteSource.None
text.AutoCompleteMode = AutoCompleteMode.None
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DataGridView1.Columns.Add("ColName", "Name")
DataGridView1.Columns.Add("ColAge", "Age")
Dim ComCol As New DataGridViewComboBoxColumn
ComCol.Items.Add(1)
ComCol.Items.Add(2)
ComCol.HeaderText = "Combobox Col"
DataGridView1.Columns.Add(ComCol)
End Sub
End Class
Do a test in Else clause as :
If header.Equals("Name") Then
If DataGridView1.CurrentCell.ColumnIndex = 0 Then
Dim text As TextBox = TryCast(e.Control, TextBox)
If text IsNot Nothing Then
text.AutoCompleteMode = AutoCompleteMode.Suggest
text.AutoCompleteSource = AutoCompleteSource.CustomSource
Dim data As AutoCompleteStringCollection = New AutoCompleteStringCollection()
appData(data, DataGridView1.CurrentCellAddress.ToString)
text.AutoCompleteCustomSource = data
End If
ElseIf TypeOf e.Control Is TextBox Then
Dim text As TextBox = TryCast(e.Control, TextBox)
text.AutoCompleteCustomSource = Nothing
text.AutoCompleteSource = AutoCompleteSource.None
text.AutoCompleteMode = AutoCompleteMode.None
End If
End If
Private Sub DataGridView1_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError
Try
Catch ex As Exception
End Try
End Sub
Use just :
If header.Equals("Name") Then
instead of :
If TypeOf e.Control Is TextBox AndAlso header.Equals("Name") AndAlso
DataGridView1.CurrentCell.ColumnIndex = 0 Then
I believe the problem is that your DataGridView1_EditingControlShowing is firing more often than you realize.
Perhaps you should just do your autocomplete work on form load event instead? That way, it only has to run once...
The 'autocomplete work' I'm talking about, being this part:
text.AutoCompleteMode = AutoCompleteMode.Suggest
text.AutoCompleteSource = AutoCompleteSource.CustomSource
Dim data As AutoCompleteStringCollection = New AutoCompleteStringCollection()
appData(data, DataGridView1.CurrentCellAddress.ToString)
text.AutoCompleteCustomSource = data

How to catch cellmouseclicks in dynamically created datagridviews on TabPages

Sub Tabs()
Dim shtWork1 As Short
Dim dbpath As String = "db\... "
Dim conn As New OleDbConnection(dbpath ... )
For shtWork1 = 1 To shtMaxTabs
Dim TabPageAll As New TabPage
Try
'define DataGridViews
Dim DataGridView1 As New DataGridView
DataGridView1.Parent = TabPageAll
.
.
.
DataGridView1.AutoGenerateColumns = True
TabControl1.TabPages.Add(TabPageAll)
Catch ex as ...
Message
Finally
Close()
End Try
Next shtWork1
End Sub
' The Grids are created on the TabPages and work fine.
But if I click on a cell it should give me the possibility to execute some other code i.e.
filling textboxes on that specific TabPage.
Any idea would be apreciated.
TIA Frank
Just add an event handler when adding your DataGridView
AddHandler DataGridView1.CellClick, AddressOf cellClickHandler
This is an example handler code
Private Sub cellClickHandler(sender As Object, e As DataGridViewCellEventArgs)
MessageBox.Show(String.Format("Row '{0}', Col '{1}'", e.RowIndex, e.ColumnIndex))
End Sub
Edit:
Complete solution
Add a tab control to a new winforms app. Just add this code to Form1 class.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim tabPageAll As New TabPage()
Dim dataGridView1 As New DataGridView()
Dim d As New Dictionary(Of String, String)() _
From {{"A", "1"}, {"B", "2"}, {"C", "3"}}
dataGridView1.AutoGenerateColumns = True
dataGridView1.DataSource = _
(From ds In d
Select New With {.Key = ds.Key, .Value = ds.Value}).ToArray()
AddHandler dataGridView1.CellClick, AddressOf cellClickHandler
tabPageAll.Controls.Add(dataGridView1)
TabControl1.TabPages.Add(tabPageAll)
TabControl1.SelectedTab = tabPageAll
End Sub
Private Sub cellClickHandler(ByVal sender As System.Object, ByVal e As DataGridViewCellEventArgs)
If e.RowIndex >= 0 AndAlso e.ColumnIndex >= 0 Then
' DataGridView.Rows() works just fine here
Dim selectedRow = CType(sender, DataGridView).Rows(e.RowIndex)
End If
End Sub

vb.net - Add Databinding to a ToolstripComboBox

i just managed to get my ToolstripComboBox to display a Datasource (Dictionary).
But now i want to add a DataBinding to the SelectedValue Property, but i doesn't work.
For a normal ComboBox it works :/..
My Code:
tscbb_Test.ComboBox.DataBindings.Add("SelectedValue", My.Settings, "Setting from mySettings")
Can somebody help?
I just tried this and it worked perfectly for me:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As New DataTable
With table.Columns
.Add("ID", GetType(Integer))
.Add("Name", GetType(String))
End With
With table.Rows
.Add(1, "Peter")
.Add(2, "Paul")
.Add(3, "Mary")
.Add(4, "John")
End With
Me.BindingSource1.DataSource = table
Me.BindingSource2.DataSource = table
With Me.ToolStripComboBox1.ComboBox
.DisplayMember = "Name"
.ValueMember = "ID"
.DataSource = Me.BindingSource1
.DataBindings.Add("SelectedValue", My.Settings, "ToolStripSelectedValue")
End With
With Me.ComboBox1
.DisplayMember = "Name"
.ValueMember = "ID"
.DataSource = Me.BindingSource2
.DataBindings.Add("SelectedValue", My.Settings, "FormSelectedValue")
End With
End Sub
I could run the project, select a different item in each ComboBox, close the project, run it again and the items I previously selected were selected again, indicating that the settings must have been saved.
I just tried this code with two settings of type Keys and it worked as expected:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim keys = [Enum].GetValues(GetType(Keys))
Me.BindingSource1.DataSource = keys
Me.BindingSource2.DataSource = keys
With Me.ToolStripComboBox1.ComboBox
.DataSource = Me.BindingSource1
.DataBindings.Add("SelectedItem", My.Settings, "ToolStripSelection")
End With
With Me.ComboBox1
.DataSource = Me.BindingSource2
.DataBindings.Add("SelectedItem", My.Settings, "FormSelection")
End With
End Sub

Vb.net ComboBox Autocomplete

I have a ComboBox with DropDownStyle = Simple and have bound it to a DataSet. What I want is : when I type 'a', I want my ComboBox to show only the items starting with the letter 'a' just Dictionary Program.
I have tried the AutoComplete property but it just shows a DropDown and that's not what I want
HERE IS MY CODE:
Private Sub TICKETING_FORM_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
da.Fill(ds, "STYLE")
bs.DataSource = ds.Tables("STYLE")
With Style_ComboBox
.DataSource = bs
.DisplayMember = "STYLE"
.ValueMember = "STYLE"
.AutoCompleteMode = AutoCompleteMode.Suggest
.AutoCompleteSource = AutoCompleteSource.ListItems
End With
End Sub
You need to set these property for AutoComplete
ComboBox1.AutoCompleteMode = AutoCompleteMode.Append
ComboBox1.DropDownStyle = ComboBoxStyle.DropDown
ComboBox1.AutoCompleteSource = AutoCompleteSource.ListItems
Private Sub TICKETING_FORM_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
da.Fill(ds, "STYLE")
bs.DataSource = ds.Tables("STYLE")
With Style_ComboBox
.DataSource = bs
.DisplayMember = "STYLE"
.ValueMember = "STYLE"
.DropDownStyle = ComboBoxStyle.DropDown
.AutoCompleteMode = AutoCompleteMode.Suggest
.AutoCompleteSource = AutoCompleteSource.ListItems
End With
End Sub
Change this Setting
DropDownStyle = DropDownList
Private Sub TICKETING_FORM_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
da.Fill(ds, "STYLE")
bs.DataSource = ds.Tables("STYLE")
With Style_ComboBox
.DataSource = bs
.DisplayMember = "STYLE"
.ValueMember = "STYLE"
.AutoCompleteMode = AutoCompleteMode.SuggestAppend ' This is necessary
.AutoCompleteSource = AutoCompleteSource.ListItems
End With
End Sub
The answers is quite simple. You load your combobox like you would normally by adding the display member and the value member. Then you load your autocomplete by the Display member and whala. Keep in mind that the auto complete function is basicly just a filter option on the display member side under normal conditions.
Here follows and example. Keep in mind that this example draws the list of names from our AD account and is nor shown here....
Dim col As New AutoCompleteStringCollection
Dim i As Integer
If Not MyUsers Is Nothing Then
For i = 0 To MyUsers.Rows.Count - 1
col.Add(MyUsers.Rows(i)("displayname").ToString)
Next
Request_ManagerComboBox.AutoCompleteSource = AutoCompleteSource.CustomSource
Request_ManagerComboBox.AutoCompleteCustomSource = col
Request_ManagerComboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend
Request_ManagerComboBox.DisplayMember = MyUsers.Rows(i - 1)("displayname").ToString
Request_ManagerComboBox.ValueMember = MyUsers.Rows(i - 1)("samAccountName").ToString
End If