【问题标题】:Accessing ComboBox.Items with Contains method for DataBound ComboBox使用 DataBound ComboBox 的 Contains 方法访问 ComboBox.Items
【发布时间】:2014-09-03 01:08:18
【问题描述】:

总结:

我想根据在运行时分配了数据源的 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 对象的集合。所以基本上它是将StringDataRowView.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

我知道这看起来很奇怪,但如果 &lt;Extension()&gt; 部分没有分开,代码美化将无法正常工作。当我尝试在我的主代码中使用我的扩展方法时,我收到一个关于我的扩展方法不是ComboBox.ObjectCollection 成员的错误,这对我来说似乎是假的,因为在扩展方法中我特别说第一个参数是@ 987654332@.

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

臭名昭著的“如何用 POTATO 进行脑外科手术”请求...

如何确定用户输入到数据绑定 ComboBox 的文本是否在数据源的项目列表中?

附注:只要有 VB.NET 对应的 C# 答案就可以了

【问题讨论】:

    标签: c# vb.net winforms combobox databound-controls


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      我认为以下代码代表了您所描述的内容。基本看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;
              };
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-06-25
        • 1970-01-01
        • 1970-01-01
        • 2020-04-19
        • 1970-01-01
        • 2012-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多