如何获取ObservableCollection新增对象对应的ListBoxItem控件实例
问题原因
你遇到的lbi为null的问题确实是容器生成异步导致的:向ObservableCollection插入数据只会触发集合变更通知,ListBox的容器生成、布局渲染属于UI线程的异步排队任务,你同步调用ContainerFromIndex时对应的ListBoxItem还未完成生成,因此返回null。
解决方案
你已经在配置中关闭了UI虚拟化,不存在项不在视口就不生成容器的问题,以下两种方案都可以正常使用:
方法1:使用Dispatcher排队执行获取逻辑(最常用)
把获取容器的逻辑通过Dispatcher放到UI线程任务队列,等容器生成任务完成后自动执行:
int idx = this.DataModels.IndexOf(currentDataModel); DataModel newDataModel = new DataModel($"Item{this.DataModels.Count}"); this.DataModels.Insert(idx, newDataModel); // 指定Loaded优先级,等UI布局、容器生成完成后执行 Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, new Action(() => { int nidx = HorizontalListBox.Items.IndexOf(newDataModel); var lbi = HorizontalListBox.ItemContainerGenerator.ContainerFromIndex(nidx) as ListBoxItem; // 此处lbi已生成,可正常执行后续位置获取、界面更新逻辑 }));
方法2:监听容器生成状态事件(精准可控)
如果需要更精准的生成通知,可以监听ItemContainerGenerator的状态变更事件,等容器生成完成后触发逻辑:
int targetInsertIndex = this.DataModels.IndexOf(currentDataModel); DataModel newDataModel = new DataModel($"Item{this.DataModels.Count}"); // 先注册事件再插入数据 HorizontalListBox.ItemContainerGenerator.StatusChanged += OnContainerGenerated; this.DataModels.Insert(targetInsertIndex, newDataModel); // 事件处理逻辑 private void OnContainerGenerated(object sender, EventArgs e) { var generator = sender as ItemContainerGenerator; // 容器生成完成时触发 if (generator.Status == GeneratorStatus.ContainersGenerated) { // 注销事件避免重复触发 generator.StatusChanged -= OnContainerGenerated; var lbi = generator.ContainerFromIndex(targetInsertIndex) as ListBoxItem; // 此处执行后续逻辑 } }
内容的提问来源于stack exchange,提问作者PeterMacGonagan
相关产品推荐
相关产品推荐

