You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过文本框搜索绑定Dictionary的ListBox 解绑是否丢失原数据

问题解答与实现方案

核心疑问解答

  • 解绑ListBox数据源会不会丢失MusicDictionary数据?
    完全不会。MusicDictionary是你独立声明的内存存储对象,ListBox的绑定只是读取它的数据用于展示,无论解绑、修改临时绑定都不会修改原Dictionary的内容,后续随时可以重新绑定原Dictionary恢复全量歌曲展示。
  • Dictionary使用注意事项
    Dictionary是键值对存储结构,要求Key全局唯一,你当前用歌曲标题作为Key需要保证没有重名歌曲,否则写入时会抛出重复键异常。如果存在重名场景,可以改用List(Of (SongTitle As String, SongLocation As String))元组列表存储数据,灵活性更高。

报错根因分析

第一次报错:System.ArgumentException: Items collection cannot be modified when the DataSource property is set.

只要ListBox的DataSource属性被赋值过,系统就会锁定Items集合禁止直接增删改,所有数据变更必须通过修改关联的数据源实现,你在未解绑的情况下直接调用ListBox1.Items.Add是报错的直接原因。同时你将ListBox1.Items本身赋值给DataSource属于循环引用,逻辑本身不成立。

调整后无内容的根因

你依然把ListBox1.Items本身赋值给DataSource,系统无法正常读取数据源内容;同时绑定键值对结构时没有指定DisplayMember(列表展示的字段)和ValueMember(选中项对应的实际值字段),ListBox不知道要渲染什么内容,所以展示为空。

正确实现代码

方案1:直接操作Items集合(简单场景适用)

不需要设置DataSource,解绑后直接操作Items即可:

Private Sub TextBoxSearchMusic_TextChanged(sender As Object, e As EventArgs) Handles TextBoxSearchMusic.TextChanged
    ' 解绑数据源,解除Items集合锁定
    ListBox1.DataSource = Nothing
    ' 清空现有展示内容
    ListBox1.Items.Clear()
    
    ' 遍历原Dictionary匹配搜索内容
    For Each songTitle As String In MusicDictionary.Keys
        If songTitle.StartsWith(TextBoxSearchMusic.Text, StringComparison.CurrentCultureIgnoreCase) Then
            ListBox1.Items.Add(songTitle)
        End If
    Next
End Sub

方案2:DataSource绑定(推荐,方便后续取歌曲路径)

通过绑定筛选后的数据源实现,不需要手动操作Items集合:

Private Sub TextBoxSearchMusic_TextChanged(sender As Object, e As EventArgs) Handles TextBoxSearchMusic.TextChanged
    ' 筛选匹配的歌曲结果
    Dim searchResult = MusicDictionary.Where(Function(kv) 
        Return kv.Key.StartsWith(TextBoxSearchMusic.Text, StringComparison.CurrentCultureIgnoreCase)
    End Function).ToList()
    
    ' 绑定搜索结果
    ListBox1.DataSource = New BindingSource(searchResult, Nothing)
    ' 指定展示字段为歌曲标题,取值字段为歌曲路径
    ListBox1.DisplayMember = "Key"
    ListBox1.ValueMember = "Value"
End Sub

恢复全量歌曲展示的示例代码

搜索结束后要还原全量列表,直接重新绑定原Dictionary即可:

ListBox1.DataSource = New BindingSource(MusicDictionary.ToList(), Nothing)
ListBox1.DisplayMember = "Key"
ListBox1.ValueMember = "Value"

内容的提问来源于stack exchange,提问作者John Henderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 22:24:06