我想针对在运行时分配了DataSource的ComboBox中的项目列表检查当前的ComboBox.text值。如果文本与列表中的项目不匹配,则它将选择列表中的第一个项目。
' This Load function is just here to give an example of how I bound the ComboBox '
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.myComboBox.DisplayMember = "something"
Me.myComboBox.ValueMember = "otherthing"
Me.myComboBox.DataSource = Me.myDataTable
End Sub
' This function is copy/pasted directly out of my code '
Private Sub myComboBox_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles myComboBox.Validating
If Not DirectCast(sender, ComboBox).Items.Contains(DirectCast(sender, ComboBox).Text) Then
DirectCast(sender, ComboBox).SelectedValue = -1
End If
End Sub
但是上面的代码没有按预期工作,因为在运行时检查myComboBox.Items
属性时,它实际上是System.Data.DataRowView
个对象的集合。所以基本上它是将String
与DataRowView.ToString()
进行比较,除非myComboBox.Text
值实际上是“System.Data.DataRowView”,否则它总是为假...
“嘿,让我们制作一个扩展方法来搜索DataViewRow
的所有项目,看看我的请求值是否在那里!”,但它没有按计划进行......
<Extension()>
Private Function Contains_databound(ByVal items As ComboBox.ObjectCollection, ByVal value As Object) As Boolean
Dim Success As Boolean = False
For Each itm In items
Dim item As DataRowView = Nothing
Try
item = DirectCast(itm, DataRowView)
Catch ex As Exception
Throw New Exception("Attempted to use a Contains_databound method on a non databound object", New Exception(ex.Message))
End Try
If Not IsNothing(item) Then
For Each rowItem In item.Row.ItemArray
Dim v1 As String = TryCast(rowItem, String)
Dim v2 As String = TryCast(value, String)
If Not IsNothing(v1) And Not IsNothing(v2) Then
If v1.Equals(v2) Then
Success = True
End If
End If
Next
End If
Next
Return Success
End Function
我知道这看起来很奇怪,但如果<Extension()>
部分没有分开,代码美化将无法正常工作。当我尝试在我的主代码中使用我的扩展方法时,我得到一个关于我的扩展方法不是ComboBox.ObjectCollection
的成员的错误,这对我来说似乎是假的,因为在扩展方法中我特别说第一个参数是ComboBox.ObjectCollection
。
Private Sub myComboBox_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles myComboBox.Validating
If DirectCast(sender, ComboBox).Items.Contains_databound(DirectCast(sender, ComboBox).Text) Then
DirectCast(sender, ComboBox).SelectedValue = -1
End If
End Sub
如何确定用户输入数据绑定ComboBox的文本是否位于DataSource的项目列表中?
附注:C#答案很好,只要他们有VB.NET对应
答案 0 :(得分:1)
您实际想要确定的是任何项目的显示文本是否与其他值匹配。要获取项目的显示文本,请调用GetItemText
。我将发布一个例子。
这是一个可以完成工作的扩展方法:
Imports System.Runtime.CompilerServices
Public Module ComboBoxExtensions
<Extension>
Public Function ContainsItemText(source As ComboBox, itemText As String) As Boolean
Return source.Items.Cast(Of Object).Any(Function(item) source.GetItemText(item) = itemText)
End Function
End Module
答案 1 :(得分:1)
我认为以下代码代表了您所描述的内容。基本上看看btn.Clicked事件代码。
public class FormAB : Form {
ComboBox combo = new ComboBox { DropDownStyle = ComboBoxStyle.DropDown, Dock = DockStyle.Top };
Button btn = new Button { Text = "Button", Dock = DockStyle.Top };
public FormAB() {
Controls.Add(btn);
Controls.Add(combo);
DataTable table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("BirthDate", typeof(DateTime));
table.Rows.Add("Alan", DateTime.Today.AddYears(-20));
table.Rows.Add("Bob", DateTime.Today.AddYears(-35));
combo.DataSource = table;
combo.DisplayMember = "FirstName";
combo.ValueMember = "FirstName";
btn.Click += delegate {
Object rv = combo.Items.Cast<Object>().Where(r => combo.GetItemText(r) == "Bob").FirstOrDefault();
// either/or
//Object rv = combo.Items.Cast<DataRowView>().Where(r => (String) r[combo.DisplayMember] == "Bob").FirstOrDefault();
if (rv == null && combo.Items.Count > 0)
rv = combo.Items[0];
combo.SelectedItem = rv;
};
}
}