Windows Community Toolkit:TokenizingTextBox动态修改SuggestedItemsSource崩溃问题
问题分析与解决方案
核心错误点
- 类型不匹配:
SuggestionList定义为List<string>,但searchName方法中添加的是originalData[i](自定义对象)而非originalData[i].Name(字符串),会引发类型转换异常。 - 集合类型选择错误:
List<T>未实现INotifyCollectionChanged,修改集合(Clear/Add)无法通知UI更新;且TokenizingTextBox绑定期间持有集合引用,直接调用Clear会导致控件访问已清空集合引发崩溃。
修正方案
1. 更换集合类型为ObservableCollection<T>
将ViewModel中的集合类型改为ObservableCollection<string>,它会自动向UI发送集合变更通知:
private ObservableCollection<string> _suggestionList = new ObservableCollection<string>(); public ObservableCollection<string> SuggestionList { get => _suggestionList; set => SetProperty(ref _suggestionList, value); }
2. 修复类型不匹配并优化集合更新逻辑
在searchName方法中,添加匹配的字符串而非原始对象,同时通过替换整个集合避免直接修改引发的控件异常:
internal void searchName(string searchString) { // 过滤出匹配的名称 var filteredNames = originalData .Where(item => item.Name.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0) .Select(item => item.Name) .ToList(); // 直接替换集合,触发UI更新 SuggestionList = new ObservableCollection<string>(filteredNames); }
3. 可选:原地更新集合(需确保UI线程操作)
若不想频繁创建新集合,可在UI线程内清空并添加元素:
internal void searchName(string searchString) { Application.Current.Dispatcher.Invoke(() => { SuggestionList.Clear(); foreach (var item in originalData.Where(i => i.Name.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)) { SuggestionList.Add(item.Name); } }); }
额外注意
- XAML中的
TextMemberPath="Text"可删除,因为绑定的是字符串类型,无需指定属性路径;若后续改用自定义对象,再对应调整该属性。 - 确保ViewModel的
SetProperty方法正确实现INotifyPropertyChanged,保证集合赋值时UI能收到更新通知。
内容的提问来源于stack exchange,提问作者CheckItOut
相关产品推荐
相关产品推荐

