WPF中GridView的ItemsSource有数据但Items.Count为0的原因是什么?
WPF中GridView.ItemsSource有值但Items.Count为0的原因解析
核心原因
- 第一是WPF的UI渲染为异步机制:你给
ItemsSource赋值之后,属性值会立刻更新,所以打印ItemsSource能拿到你设置的集合对象。但Items集合的同步更新需要等待UI线程的渲染调度完成,你在赋值后立刻打印Items.Count的时候,UI还没完成集合项的生成工作,此时Items还是空集合,所以输出为0。 - 第二是数据源类型不匹配WPF绑定规则:你使用的
List<T>没有实现WPF绑定要求的INotifyCollectionChanged接口,绑定引擎无法感知集合的内容变更/首次赋值,不会主动触发Items集合的同步,也会导致这个问题。 - 第三是操作线程不合法:如果你是在后台工作线程给
ItemsSource赋值,虽然属性值会被写入,但是WPF的绑定机制会忽略非UI线程的控件属性变更通知,不会触发后续的Items集合更新,最终也会出现Items.Count为0的情况。
基础代码修正提示
你提供的示例代码存在语法错误,需要先修正避免基础逻辑问题:
- 重复定义了
user1变量,第二个User实例应该命名为user2 - 给UserId、UserName赋值时使用的
user变量未定义,应该对应user1、user2
// 修正后的示例代码 public class User { public int UserId { get; set; } public string UserName { get; set; } } List<User> ListOfusers = new List<User>(); User user1 = new User(); user1.UserId = 1; user1.UserName= "John"; User user2 = new User(); user2.UserId = 2; user2.UserName= "Mike"; ListOfusers.Add(user1); ListOfusers.Add(user2);
解决方法
- 优先用
ObservableCollection<T>替代List<T>作为数据源,该类原生实现了INotifyCollectionChanged接口,集合变更时会主动通知UI同步Items集合。 - 若必须在赋值后立刻访问
Items集合,可以将访问逻辑调度到UI线程的渲染完成阶段执行,示例如下:
GridView1.ItemsSource = ListOfusers; // 等待UI渲染完成后再读取Items.Count GridView1.Dispatcher.Invoke(() => { Console.WriteLine(GridView1.Items.Count); }, System.Windows.Threading.DispatcherPriority.Loaded);
- 确认所有对
ItemsSource的赋值操作都在UI线程执行,不要在后台线程直接操作UI控件的属性。
内容的提问来源于stack exchange,提问作者abdou93
相关产品推荐
相关产品推荐

