[英]Accessing ComboBox.Items with Contains method for DataBound ComboBox
I want to check the current ComboBox.text value against the list of items in a ComboBox that is assigned a DataSource at run time. 我想对照在运行时分配了数据源的ComboBox中的项目列表检查当前ComboBox.text值。 If the text doesn't match an item in the list then it will select the first item in the list. 如果文本与列表中的项目不匹配,则它将选择列表中的第一项。
' 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
However the above code does not work as expected because when inspecting the myComboBox.Items
property at run time, it is actually a collection of System.Data.DataRowView
objects. 但是上述代码无法按预期方式工作,因为在运行时检查myComboBox.Items
属性时,它实际上是System.Data.DataRowView
对象的集合。 So basically it is comparing a String
to DataRowView.ToString()
which is always false unless the myComboBox.Text
value is in fact "System.Data.DataRowView"... 因此,基本上它将String
与DataRowView.ToString()
进行比较,除非myComboBox.Text
值实际上是“ System.Data.DataRowView”,否则它始终为false。
"Hey, lets make an extension method to search all the items of the DataViewRow
and see if my requested value is in there!", but it's not going as planned... “嘿,让我们做一个扩展方法来搜索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
I know that looks weird, but the code prettify won't work right if the <Extension()>
part isn't separated. 我知道这看起来很奇怪,但是如果未分隔<Extension()>
部分,则整理代码将无法正常工作。 When I attempt to use my extension method in my main code, I get an error about my extension method not being a member of ComboBox.ObjectCollection
which seems bogus to me because in the extension method I am specifically saying that the first parameter is a ComboBox.ObjectCollection
. 当我尝试在我的主代码中使用扩展方法时,我得到一个关于我的扩展方法不是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
How can I determine that the text a user inputs into a databound ComboBox is in the list of items from the DataSource? 如何确定用户输入到数据绑定的ComboBox中的文本在DataSource的项目列表中?
Side note: C# answers are fine so long as they have a VB.NET counterpart 旁注:C#答案很好,只要它们具有VB.NET副本即可
What you're actually trying to determine is whether the displayed text of any item matches some other value. 您实际上要确定的是任何项目的显示文本是否与其他值匹配。 To get the displayed text of an item you call GetItemText
. 要获取项目的显示文本,请调用GetItemText
。 I'll post an example. 我将举一个例子。
Here's an extension method that will do the job: 这是可以完成这项工作的扩展方法:
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
I think the following code represents what you described. 我认为以下代码代表了您所描述的内容。 Basically look at the btn.Clicked event code. 基本上看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;
};
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.