如何结合ListView实现ObservableCollection?类型转换错误求助
我来帮你搞定这个问题,咱们一步步梳理清楚:
首先,你遇到的类型转换错误核心原因是**DataView和ObservableCollection<DataView>完全不是同类型**——dt.DefaultView返回的是一个包含DataRowView对象的集合容器,而你声明的List属性是ObservableCollection<DataView>,类型不匹配自然会报错。另外,ObservableCollection本身也没有Delete方法,这也是后续要修正的细节。
下面是完整的解决方案:
1. 修正ObservableCollection的泛型类型
把List属性的泛型从DataView改成DataRowView,因为DataView中的每一项都是DataRowView对象:
private ObservableCollection<DataRowView> _list; public ObservableCollection<DataRowView> List { get => _list; private set { _list = value; OnPropertyChanged(nameof(List)); // 后续实现INotifyPropertyChanged后添加 } }
2. 将DataView转换为ObservableCollection
遍历DataView中的每一项,逐个添加到新的ObservableCollection实例中,完成类型转换:
private void LoadData() { DataTable dt = new DataTable(); using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["StringConnexion"].ConnectionString)) { SqlDataAdapter adapter = new SqlDataAdapter(); adapter.SelectCommand = new SqlCommand("Select * from dbo.users", connection); adapter.Fill(dt); } // 把DataView的内容转成ObservableCollection var dataView = dt.DefaultView; List = new ObservableCollection<DataRowView>(); foreach (DataRowView rowView in dataView) { List.Add(rowView); } }
3. 修正删除方法的调用
ObservableCollection没有Delete方法,改用RemoveAt移除指定索引的项,同时添加索引越界判断避免报错:
public void somethingABC() { if (List != null && List.Count > 2) { List.RemoveAt(2); } }
4. (推荐)实现INotifyPropertyChanged接口
为了确保List属性重新赋值时UI能收到通知,让ViewModel实现INotifyPropertyChanged接口:
public class TestViewModel : INotifyPropertyChanged { // ... 前面的属性和方法代码 ... public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
为什么这样能实现实时更新?
ObservableCollection<T>内置了INotifyCollectionChanged接口,当你执行Add、RemoveAt、Clear等操作时,它会自动向ListView发送集合变化通知,UI会立刻刷新显示最新数据。
另外,你的XAML代码不需要修改,因为DataRowView可以通过绑定路径直接访问DataTable的列(比如Login、password),原有绑定逻辑依然有效。
内容的提问来源于stack exchange,提问作者Black Panther

