我的应用程序中有一个组合框,其中包含来自SQL SERVER的十几个项目。我目前正在尝试允许用户能够在组合框中键入新值并将其保存到SQL SERVER中的表中。我正在寻找DropDown和DropDownList的DropDownStyle的东西。基本上我希望让用户键入组合框,但是如果值不存在,我希望能够给他们一个保存它的选项(可能是丢失焦点)。我想知道做这样的事情的好方法。
在失去焦点时,我应该基本上查看当前在下拉菜单中的每个项目,并根据输入的值检查它吗?
编辑:
Sql="SELECT IDvalue, TextName from TblReference"
Dim objconn As New SqlConnection
objconn = New SqlConnection(conn)
objconn.Open()
Dim da As New SqlDataAdapter(sql, objconn)
Dim ds As New DataSet
da.Fill(ds, "Name")
If ds.Tables("Name").Rows.Count > 0 Then
Dim dr As DataRow = ds.Tables("Name ").NewRow
ds.Tables("Name").Rows.InsertAt(dr, 0)
With c
.DataSource = ds.Tables("Name")
.ValueMember = " IDvalue "
.DisplayMember = " TextName "
End With
End If
答案 0 :(得分:1)
我这样做的方法是在窗口加载时执行新的SQL查询以获取表中的值列表,并将它们加载到组合框中。
然后,一旦焦点丢失,它就会根据已加载的当前值检查当前键入组合框的内容。如果它不存在,那么它不在SQL中。像下面这样......
Dim found As Boolean = False
For i As Integer = 0 To comboBox.Items.Count - 1
Dim value As String = comboBox.Items(i).ToString()
If comboBox.Text = value Then
found = True
End If
Next
If found = False Then
'the item doesn't exist.. add it to SQL
Else
'the item exists.. no need to touch SQL
End If
答案 1 :(得分:1)
我要做的第一件事就是建立一个简单的类来通过这个类的List
来保存你的值Public Class DataItem
Public Property IDValue As Integer
Public Property TextName as String
End Class
现在,不是构建SqlDataAdapter并填充数据集,而是使用SqlDataReader并构建List(Of DataItem)
' Class global...
Dim allItems = new List(Of DataItem)()
Sql="SELECT IDvalue, TextName from TblReference"
' Using to avoid leaks on disposable objects
Using objconn As New SqlConnection(conn)
Using cmd As New SqlCommand(Sql, objconn)
objconn.Open()
Using reader = cmd.ExecuteReader()
While reader.Read()
Dim item = new DataItem() With { .IDValue = reader.GetInt32(0), .TextName = reader.GetString(1)}
allItems.Add(item)
End While
End Using
if allItems.Count > 0 Then
allItems.Insert(0, new DataItem() With {.IDValue = -1, .TextValue = ""}
Dim bs = new BindingList(Of DataItem)(allItems)
c.DataSource = bs
c.ValueMember = "IDvalue"
c.DisplayMember = "TextName"
End If
End Using
End Using
现在要添加到组合框的Leave事件的代码
Sub c_Leave(sender As Object, e As EventArgs) Handles c.Leave
If Not String.IsNullOrEmpty(c.Text) Then
Dim bs = DirectCast(c.DataSource, BindingList(Of DataItem))
if bs.FirstOrDefault(Function(x) x.TextName = c.Text) Is Nothing Then
Dim item = new DataItem() With { .IDValue = -1, .TextName = c.Text}
bs.Add(item)
' here add the code to insert in the database
End If
End If
End Sub
答案 2 :(得分:1)
您已经在表格中添加了假/空行,您可以为新项目执行相同操作。
' form level datatable var
Private cboeDT As DataTable
初始化:
cboeDT = New DataTable
Dim sql = "SELECT Id, Descr FROM TABLENAME ORDER BY Descr"
Using dbcon As New MySqlConnection(MySQLConnStr)
Using cmd As New MySqlCommand(sql, dbcon)
dbcon.Open()
cboeDT.Load(cmd.ExecuteReader())
' probably always need this even
' when there are no table rows (???)
Dim dr = cboeDT.NewRow
dr("Id") = -1 ' need a way to identify it
dr("Descr") = ""
cboeDT.Rows.InsertAt(dr, 0)
End Using
End Using
cboeDT.DefaultView.Sort = "Descr ASC"
cboE.DataSource = cboeDT
cboE.DisplayMember = "Descr"
cboE.ValueMember = "Id"
注意用户倾向于优先考虑这些事情的顺序。这些简单的生物往往更倾向于按字母顺序排列,而不是数字标识。为了适应它们,DefaultView
被排序,以便添加的任何新行将以正确的顺序显示。
在离开事件中添加新项目(非常像史蒂夫')
Private Sub cboE_Leave(sender ...
' if it is new, there will be no value
If cboE.SelectedValue Is Nothing Then
' alternatively, search for the text:
'Dim item = cboeDT.AsEnumerable().
' FirstOrDefault(Function(q) String.Compare(q.Field(Of String)("Descr"),
' cboE.Text, True) = 0)
'If item Is Nothing Then
' ' its new...
Dim newid = AddNewItem(cboE.Text)
Dim dr = cboeDT.NewRow
dr("Id") = newid
dr("Descr") = cboE.Text
cboeDT.Rows.Add(dr)
' fiddling with the DS looses the selection,
' put it back
cboE.SelectedValue = newid
End If
End Sub
如果您想按文字搜索:
Dim item = cboeDT.AsEnumerable().
FirstOrDefault(Function(q) String.Compare(q.Field(Of String)("Descr"),
cboE.Text, True) = 0)
If item Is Nothing Then
' its new...
...
根据实际的数据库,插入会有所不同。但关键的一步是捕获并返回新项目的ID,因为CBO需要它:
Private Function AddNewItem(newItem As String) As Int32
Dim sql = "INSERT INTO MY_TABLE (Descr) VALUES (@v); SELECT LAST_INSERT_ID();"
Dim newId = -1
Using dbcon As New MySqlConnection(MySQLConnStr)
Using cmd As New MySqlCommand(sql, dbcon)
dbcon.Open()
cmd.Parameters.Add("@v", MySqlDbType.String).Value = newItem
' MySql provides it in the command object
If cmd.ExecuteNonQuery() = 1 Then
newId = Convert.ToInt32(cmd.LastInsertedId)
End If
End Using
End Using
Return newId
End Function
如上所述,MySql
提供LastInsertedID
作为命令对象属性。在SQL SERVER中,将...";SELECT LAST_INSERT_ID();"
添加到SQL的末尾,然后:
newId = Convert.ToInt32(cmd.ExecuteScalar())
这在概念上与史蒂夫的回答没有什么不同,除了它使用你构建的DataTable
而不是使它(非常)稍微简单的集合。