Bounded ComboBox AutoComplete Sort - vb.net

I have a bounded Combobox and it's data source is sorted but it seems that auto complete re-sort its items when I start typing.
For example I use this code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt As New DataTable
With dt
.Columns.Add("id", GetType(Long))
.Columns.Add("Name", GetType(String))
.Rows.Add({1, "John"})
.Rows.Add({2, "Jan"})
End With
With Me.ComboBox1
.DataSource = dt
.ValueMember = "id"
.DisplayMember = "Name"
.DropDownStyle = ComboBoxStyle.DropDown
.AutoCompleteMode = AutoCompleteMode.SuggestAppend
.AutoCompleteSource = AutoCompleteSource.ListItems
End With
End Sub
Now when I type j, the Combobox suggest Jan but I want the first item John.
For unbounded Combobox, this works: How to provide automatic text completion for a ComboBox control in Visual Basic .NET or in Visual Basic 2005 and also this question is For unbounded Combobox.

I modified the code in this link and now it works as needed:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt As New DataTable
With dt
.Columns.Add("id", GetType(Long))
.Columns.Add("Name", GetType(String))
.Rows.Add({1, "John"})
.Rows.Add({2, "Jan"})
End With
With Me.ComboBox1
.DataSource = dt
.ValueMember = "id"
.DisplayMember = "Name"
.DropDownStyle = ComboBoxStyle.DropDown
.AutoCompleteMode = AutoCompleteMode.None
End With
End Sub
Private Sub ComboBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles ComboBox1.KeyUp
' Do nothing for some keys such as navigation keys.
If ((e.KeyCode = Keys.Back) Or
(e.KeyCode = Keys.Left) Or
(e.KeyCode = Keys.Right) Or
(e.KeyCode = Keys.Up) Or
(e.KeyCode = Keys.Delete) Or
(e.KeyCode = Keys.Down) Or
(e.KeyCode = Keys.PageUp) Or
(e.KeyCode = Keys.PageDown) Or
(e.KeyCode = Keys.Home) Or
(e.KeyCode = Keys.End)) Then
Return
End If
Dim actual As String = Me.ComboBox1.Text
Dim dt As DataTable = Me.ComboBox1.DataSource
Dim dr = dt.Select("Name like '" & actual & "%'")
If dr.Count > 0 Then
Dim found As String
With Me.ComboBox1
.DroppedDown = True
Cursor.Current = Cursors.Default 'to show the cursor again
found = dr(0)("Name")
.Text = found
.SelectionStart = actual.Length
.SelectionLength = found.Length
End With
End If
End Sub
I added this line Cursor.Current = Cursors.Default to resolve this problem.

Related

How to filter rows in listview based on matching value with textbox in vb.net

I am making billing software. Here if we press any key in datagridview1 third column listview2 populate from datatable dt9. After that if we type in textbox11 then textchangevent will filter datatable according to datatable value matching with textbox11.text.
Here is my code.
Private Sub DataGridView1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles DataGridView1.KeyPress
Dim c2 As DataGridViewCell = DataGridView1.CurrentCell
If c2.ColumnIndex = 3 Then
If (Char.IsControl(e.KeyChar)) Then Return
If Trim(DataGridView1.Rows(c2.RowIndex).Cells(2).Value).Length = 0 AndAlso DataGridView1.Rows(c2.RowIndex).Cells(6).ReadOnly = True Then
MsgBox("Please Enter the Item Name.")
End If
End If
If c2.ColumnIndex = 2 Then
If (Char.IsControl(e.KeyChar)) Then Return
TextBox12.Text = Integer.Parse(c2.RowIndex)
conn9.Open()
Dim strSQL9 As String
Dim cmd9 As SqlCommand
Dim da9 As SqlDataAdapter = New SqlDataAdapter
Dim df As New DataTable
dt9.Clear()
strSQL9 = "Select Col_Barcode as Barcode,Col_Pro_Name as Item,Col_Pack_Size as [Pack Size],Col_Brand as Brand,Col_Curr_Stock as Stock,Col_Base_Rate as DPL,Col_A_Rate as [Rate A],Col_B_Rate as [Rate B],Col_C_Rate as [Rate C],Col_D_Rate as [Rate D] From Tab_Item_M where Col_Pro_Name IS NOT NULL Order by Col_Pro_Name ASC"
cmd9 = New SqlCommand(strSQL9, conn9)
cmd9.CommandType = CommandType.Text
da9.SelectCommand = cmd9
da9.Fill(dt9)
conn9.Close()
Panel7.Visible = True
Panel7.Size = New Size(1007, 375)
TextBox11.Text = e.KeyChar
TextBox11.Focus()
TextBox11.Select(TextBox11.Text.Length, 0)
End If
e.Handled = True
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Timer1.Interval = 250
Timer1.Stop()
Dim df As DataTable = dt9.Clone
df.Clear()
Dim Rows As DataRow() = dt9.[Select]("Item like '%" & TextBox11.Text & "%'")
For Each row As DataRow In Rows
df.ImportRow(row)
Next
With ListView2
.View = View.Details
.GridLines = True
.Columns.Clear()
.Items.Clear()
End With
For Each col As DataColumn In df.Columns
ListView2.Columns.Add(col.ToString)
Next
For Each row As DataRow In df.Rows
Dim lst1 As ListViewItem = ListView2.Items.Add(If(row(0) IsNot Nothing, row(0).ToString, String.Empty))
For i As Integer = 1 To df.Columns.Count - 1
lst1.SubItems.Add(If(row(i) IsNot Nothing, row(i).ToString, String.Empty))
Next
Next
ListView2.Columns.Item(0).Width = 70
ListView2.Columns.Item(1).Width = 300
ListView2.Columns.Item(2).Width = 90
ListView2.Columns.Item(3).Width = 100
ListView2.Columns.Item(5).Width = 70
End Sub
Private Sub TextBox11_TextChanged(sender As Object, e As EventArgs) Handles TextBox11.TextChanged
Timer1.Stop()
Timer1.Start()
End Sub
The problem is sometime it not work but sometime works.
Is my codes are correct? I am new in coding. Please give me your suggestion. Thanks in advance.

Set color of specific item within a DataGridViewComboBox dropdown list

In the following example, how can I highlight (change the background color) of specific items in the dropdown list? To be specific, I am talking about the items in the "dropdown list" for the DataGridViewComboBox.
I want to highlight for the user the specific item(s) that are bad choices.
Please provide a working code example in vb.net.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt As New DataTable
dt.Columns.Add("id", GetType(Integer))
dt.Columns.Add("list", GetType(String))
dt.Columns.Add("goodChoice", GetType(Boolean))
dt.Rows.Add(10, "Lemon")
dt.Rows.Add(20, "Apple")
dt.Rows.Add(30, "Star Fruit", False)
dt.Rows.Add(40, "Orange")
Dim newColumn As New DataGridViewComboBoxColumn()
With newColumn
.HeaderText = "Choices"
.Name = "Choices"
.DataSource = dt
.DisplayMember = "list"
.ValueMember = "id"
End With
DataGridView1.Columns.Add(newColumn)
End Sub
Try handling the EditingControlShowing event to subscribe to the ComboBox.DrawItem event. In this event handler you'll grab the underlying DataTable DataSource. When that item's goodChoice is False and the item is not the focused item, fill it's background color.
Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
If TypeOf e.Control Is ComboBox Then
Dim cb As ComboBox = TryCast(e.Control, ComboBox)
cb.DrawMode = DrawMode.OwnerDrawFixed
RemoveHandler cb.DrawItem, AddressOf DrawGridComboBoxItem
AddHandler cb.DrawItem, AddressOf DrawGridComboBoxItem
End If
End Sub
Private Sub DrawGridComboBoxItem(sender As Object, e As DrawItemEventArgs)
If e.Index <> -1 Then
e.DrawBackground()
Dim cb As ComboBox = TryCast(sender, ComboBox)
Dim dt As DataTable = TryCast(cb.DataSource, DataTable)
If (e.State And DrawItemState.Focus) <> DrawItemState.Focus AndAlso cb.DroppedDown Then
If dt.Rows(e.Index).Item("goodChoice") Then
e.Graphics.FillRectangle(Brushes.White, e.Bounds)
Else ' Added for follow-up question.
e.Graphics.FillRectangle(Brushes.Red, e.Bounds)
End If
End If
e.Graphics.DrawString(dt.Rows(e.Index).Item("Name"), e.Font, Brushes.Black, e.Bounds)
e.DrawFocusRectangle()
End If
End Sub
My follow-up question is, if and when the red colored item is selected, how can I make the color stick when exiting the edit mode of the control?
Set the BackColor of the cell itself. (Note: This will also alter the dropped down items, so we add an Else statement to the DrawGridComboBoxItem method above.)
Set the color when the cell value changes:
Private Sub DataGridView1_ValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
If TypeOf DataGridView1.CurrentCell Is DataGridViewComboBoxCell Then
Dim cell As DataGridViewComboBoxCell = TryCast(DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex), DataGridViewComboBoxCell)
Dim dt As DataTable = TryCast(cell.DataSource, DataTable)
Dim row() As DataRow = dt.Select("ID = " & cell.Value)
cell.Style.BackColor = If(row(0).Item("goodChoice"), SystemColors.ControlLight, Color.Red)
End If
End Sub
Then use that color by manually painting the background:
Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
If e.RowIndex >= 0 And e.ColumnIndex >= 0 Then
If TypeOf DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex) Is DataGridViewComboBoxCell Then
Dim cell As DataGridViewComboBoxCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex)
Dim color As Color = If(cell.Style.ForeColor.Name = "0", Color.Black, cell.Style.ForeColor)
Using backbrush = New SolidBrush(cell.Style.BackColor)
Using brush = New SolidBrush(color)
Using format = New StringFormat()
e.Paint(e.ClipBounds, DataGridViewPaintParts.Background)
e.Paint(e.ClipBounds, DataGridViewPaintParts.Border)
e.Paint(e.ClipBounds, DataGridViewPaintParts.ContentBackground)
e.Paint(e.ClipBounds, DataGridViewPaintParts.ErrorIcon)
e.Paint(e.ClipBounds, DataGridViewPaintParts.Focus)
e.Paint(e.ClipBounds, DataGridViewPaintParts.SelectionBackground)
format.LineAlignment = StringAlignment.Center
Dim rect = New Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, e.CellBounds.Width - 19, e.CellBounds.Height - 3)
e.Graphics.FillRectangle(backbrush, rect)
e.Graphics.DrawString(cell.FormattedValue, e.CellStyle.Font, brush, e.CellBounds, format)
e.Handled = True
End Using
End Using
End Using
End If
End If
End Sub

Runtime datatable update error

I have a datagridview with a checkbox column. When I click(check/Uncheck) on checkbox field as random, two other fields in corrensponding row should be added OR removed in a datatable (declared runtime).
So that I can do some procedures with data in the datatable.
For that I have declared a datatable as global.
Now the problem is, each time when I click on a checkbox, a simple mouse scrolling is required to update datatable, OR a click needed in the new datagridview which is showing values in the datatable.
My code given below,
global declaration: Public PaymentTable As DataTable
Private Sub ShowOrdersFrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DataBind()
Me.DGVOrders.RowsDefaultCellStyle.BackColor = Color.GhostWhite
Me.DGVOrders.AlternatingRowsDefaultCellStyle.BackColor = Color.PaleGoldenrod
PaymentTable = New DataTable()
PaymentTable.Columns.Add("RowId", GetType(Integer))
PaymentTable.Columns.Add("Amount", GetType(Decimal))
End Sub
Private Sub DataBind()
DGVOrders.DataSource = Nothing
DGVOrders.Columns.Clear()
Dim cmd As New SqlCommand
Dim da As New SqlDataAdapter
Dim dt As New DataTable
con.Open()
With cmd
.Connection = con
.CommandText = "select * from VIEW_PAYMENTS_DUES_BYORDER where CustCode='" & CustCode & "' order by OrderNo DESC"
End With
da.SelectCommand = cmd
da.Fill(dt)
BindingSource1.DataSource = dt
DGVOrders.DataSource = BindingSource1
DGVOrders.ClearSelection()
con.Close()
DGVOrders.Columns(0).Visible = False
DGVOrders.Columns(1).HeaderText = "Order No"
DGVOrders.Columns(2).HeaderText = "Cust Code"
DGVOrders.Columns(3).HeaderText = "Name"
DGVOrders.Columns(4).HeaderText = "Order Date"
DGVOrders.Columns(5).HeaderText = "Order Price"
DGVOrders.Columns(6).HeaderText = "Total Payment"
DGVOrders.Columns(7).HeaderText = "Dues"
For i = 0 To DGVOrders.RowCount - 1
If DGVOrders.Rows(i).Cells(7).Value > 0 Then
DGVOrders.Rows(i).Cells(7).Style.ForeColor = System.Drawing.Color.Red
Else
DGVOrders.Rows(i).Cells(7).Style.ForeColor = System.Drawing.Color.Green
End If
Next
' CHECK BOX
Dim colmnchk As New DataGridViewCheckBoxColumn
colmnchk.DataPropertyName = "chkSelect"
colmnchk.HeaderText = "SELECT"
colmnchk.Name = "chkSelect"
DGVOrders.Columns.Add(colmnchk)
For i = 0 To DGVOrders.RowCount - 1
Next
'CHECK BOX END
End Sub
Private Sub DGVOrders_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGVOrders.CellValueChanged
If DGVOrders.Columns(e.ColumnIndex).Name = "chkSelect" Then
Dim checkCell As DataGridViewCheckBoxCell = _
CType(DGVOrders.Rows(e.RowIndex).Cells("chkSelect"), _
DataGridViewCheckBoxCell)
If checkCell.Value = True Then
PaymentTable.Rows.Add(DGVOrders.Rows(e.RowIndex).Cells(0).Value, DGVOrders.Rows(e.RowIndex).Cells(7).Value)
Else
Dim toRemoveID As Integer = DGVOrders.Rows(e.RowIndex).Cells(0).Value
For i = 0 To PaymentTable.Rows.Count - 1
If PaymentTable.Rows(i).Item(0) = toRemoveID Then
PaymentTable.Rows(i).Delete()
Exit Sub
End If
Next
End If
DataGridView1.DataSource = PaymentTable
End If
End Sub
Can sombody to solve the issue, or is there any other good method if my code is wrong ?
Try using a different event like CellContentClick and testing for the ColumnIndex. The drawback with this is the event will fire whenever you click on any cell.
Private Sub DGVOrders_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGVOrders.CellContentClick
'Only interested in the CheckBox column
If e.ColumnIndex = colmnchk.Index Then
Debug.WriteLine("In DGVOrders_CellContentClick for the checkbox")
End If
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

conversion from string to type boolean is not valid

The error occurs on the line If wba.Selected = "MARKETING CODE" Then ... Hopefully someone might be able to help. Thanks
'Private Sub NewRecord_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
markCodes = New DataGridViewComboBoxColumn()
markCodes.Name = "Marketing Codes"
Me.DataGridView1.Columns.Add(markCodes)
markCodes.Visible = False
End Sub
'Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)
If DataGridView1.CurrentCell.ColumnIndex = DataGridView1.Columns(wba.Name).Index Then
If TypeOf e.Control Is ComboBox Then
cbxWba = TryCast(e.Control, ComboBox)
RemoveHandler cbxWba.SelectionChangeCommitted, New EventHandler(AddressOf cbxWba_SelectionChangeCommitted)
AddHandler cbxWba.SelectionChangeCommitted, New EventHandler(AddressOf cbxWba_SelectionChangeCommitted) 'this event will fire up if there's a selected item.
End If
End If
End Sub
'Private Sub cbxWba_SelectionChangeCommitted(ByVal sender As Object, ByVal e As EventArgs)
loadDescriptions()
End Sub
Private Sub loadDescriptions()
If wba.Selected = "MARKETING CODE" Then
markCodes.Visible = True
Try
Dim con As New SqlConnection
con.ConnectionString = ""
Dim myCommand1 As New SqlClient.SqlCommand
Dim myAdapter1 As New SqlClient.SqlDataAdapter
Dim sql As String = "Select analysis_a + ' - ' + [desc] as Expr1 from marketingCode"
Dim ds As New DataSet
myCommand1.Connection = con
myCommand1.CommandText = sql
myAdapter1.SelectCommand = myCommand1
myCommand1.Connection.Open()
myAdapter1.Fill(ds)
myCommand1.Connection.Close()
Dim dt As New DataTable
dt = ds.Tables(0)
For Each row As DataRow In ds.Tables(0).Rows
DataGridView1.CurrentRow.Cells(description.Name).Value = row("Expr1").ToString()
markCodes.DataSource = dt
markCodes.DisplayMember = "Expr1"
markCodes.ValueMember = "Expr1"
Next
Catch
MsgBox("failed")
End Try
End If
End Sub
What is wba? The .Selected sounds like you are comparing a boolean property to an string.
Looking at your code, I assume that wba is a datagridviewrow, and then you cant use .Selected in that way.
To check for a value of the first selected cell in the datagridview:
With DataGridView1
If .SelectedCells.Count > 0 Then
If .SelectedCells(0).Value = "MARKETING CODE" Then
'we have a hit
End If
End If
End With
or, if you allready know what cell it is and has stored the selected cell in the wba-variable:
If wba.Value = "MARKETING CODE" Then
'we have a hit
End If
If you have selectionmode=fullrowselect and want to check if first cell in the first selected datagridviewrow has a value:
With DataGridView1
If .SelectedRows.Count > 0 Then
If .SelectedRows(0).Cells(0).Value = "MARKETING CODE" Then
'we have a hit
End If
End If
End With
If you have the row stored in the wba, and want to check if the first cell in that row has a specific value then its like this:
If wba.Cells(0).Value = "MARKETING CODE" Then
'we have a hit
End If