如何通过文本框搜索绑定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
相关产品推荐
相关产品推荐

