【问题标题】:Set SelectedItem on ListBox bound to DataTable在绑定到 DataTable 的 ListBox 上设置 SelectedItem
【发布时间】:2012-09-28 13:57:04
【问题描述】:

所以这看起来应该很容易,但是我不太清楚这里需要的语法,因为我更习惯于 WPF / c#。基本上我有一个绑定到 DataTable 的 ListBox,我想根据 ID 值选择一个项目。像这样的。

lstUsers.DataSource = dtUsers
lstUsers.DisplayMember = "UserName"
lstUsers.SelectedItem = dtUsers.Select(String.Format("ID = {0}", myID))(0)

我可以看到dtUsers.Select(String.Format("ID = {0}", myID))(0) 在调试器中返回了正确的 DataRow,但设置 SelectedItem 没有任何作用。我确定我在这里遗漏了一些明显的东西,但是我尝试过的一切都没有效果。

【问题讨论】:

    标签: vb.net winforms .net-4.0 datatable listbox


    【解决方案1】:

    你可以使用LINQ-To-DataSet:

    var rows = dtUsers.AsEnumerable()
                       .Select((row,index) => new{ row,index })
                       .Where(x => x.row.Field<int>("ID")==myID);
    if(rows.Any())
        lstUsers.SelectedIndex = rows.First().index;
    

    在 VB.NET 中:

    Dim rows = dtUsers.AsEnumerable().
        Select(Function(r, i) New With {.row = r, .index = i}).
        Where(Function(x) x.row.Field(Of Int32)("ID") = myID)
    If rows.Any Then
        lstUsers.SelectedIndex = rows.First().index
    End If
    

    注意,需要添加Imports System.Linq(C#中为using System.Linq;

    【讨论】:

    • 这是在 VB 而不是 c# 中,即使它是一个 .NET 4.0 项目,它也是最近转换的,我宁愿在没有 LINQ 的情况下完成这个,所以我不必添加更多的 DLL 引用项目。
    • @KDiTraglia:我忽略了 VB.NET 标签,抱歉。 LINQ's System.Core.dll 通常会在 4.0 中自动添加。
    • 它适用于新项目,但它是从旧的 vb6 应用程序转换而来的(而且我宁愿不为这种微不足道的更改添加 DLL 引用)。我找到了一个解决方案见下文,它在没有 LINQ 的情况下很容易做到这一点。不过感谢您的回答。
    【解决方案2】:

    您在问题中使用的SelectedItem 实际上比SelectedIndexSelectedValue 提供的答案更可靠。

    • SelectedIndex 很容易越界然后抛出异常。

    • 如果两个项目导致相同的ToString()SelectedValue 会找到错误的值

    • SelectedItem 直接匹配列表项后面的对象。如果没有匹配项,则列表框将不包含所选项目。您在问题示例中犯的唯一错误是您尝试将String 分配给SelectedItem,但最初您没有使用字符串填充SelectedItem。您的DataSource 中的每个项目的类型是什么?使用那个就行了。

    示例:如果您将 myClass 类型的项目 i1i2i3 添加到 ListBox.Items 中,它们将在 ListBox 中显示它们的值 i1.ToString()i2.ToString()i3.ToString(),但在 ListBox.Items 集合中它们将保持为 i1i2、@ 987654340@。然后你可以使用ListBox.SelectedItem = i2 并且项目i2 将被选中。但是如果你尝试ListBox.SelectedItem = i2.ToString()它不会工作,因为没有没有匹配。这是您在问题示例中尝试的内容以及为什么它不起作用。

    如果您使用列表中的对象,请在您的工作中坚持使用SelectedItem,不要使用有其缺点的SelectedIndexSelectedValue

    【讨论】:

      【解决方案3】:

      请改用此代码。

      for (var i = 0; i < lstUsers.Items.Count; i++)
          if ((listBox1.Items[i] as YourClass).ID == myID)
            listBox1.SelectedIndex = i;
      

      【讨论】:

      • 这似乎不起作用,YourClass 在这种情况下将是一个 DataRow 并且它给了我一个无效的演员表。这也是在 VB 中,而不是在 c# 中。
      【解决方案4】:

      我找到了解决办法

      lstUsers.DataSource = dtUsers
      lstUsers.DisplayMember = "UserName"
      lstUsers.ValueMember = "ID"
      lstUsers.SelectedValue = dtUsers.Select(String.Format("ID = {0}", myID))(0)("ID")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-26
        • 2011-01-02
        • 1970-01-01
        • 2019-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多