我在WPF和C#中有一个listview,它使用ObservableCollection来填充数据。当某个事件被触发时,我调用一个函数来向集合中插入一个新行。然后我需要访问该行中的控件。
我遇到的问题是,在插入行之后,我尝试遍历listview行,此行在循环中显示为null。
if (addNewNote)
{
_resultsCollection.Insert(0, new ResultsData
{
Notes = "Data to Insert",
// ... rest of fields
});
} // end if (addNewNote)
for (int currRowIndex = 0; currRowIndex < this.ResultsList.Items.Count; currRowIndex++)
{
System.Windows.Controls.ListViewItem currRow =
(System.Windows.Controls.ListViewItem)this.ResultsList.ItemContainerGenerator.ContainerFromIndex(currRowIndex);
if (currRow != null)
{
System.Windows.Controls.TextBox tb = FindByName("EditNotesTextBox", currRow) as System.Windows.Controls.TextBox;
// do stuff with controls ...
}
}
当currRowIndex为零时,currRow始终为null。
不应该是这种情况,因为我刚刚添加了它。是因为我试图在插入它的同一个函数中访问它,listview还没有更新?我可以访问listview中的每一行。有更好的解决方案吗?谢谢!
答案 0 :(得分:2)
为了首先可以访问新添加的项目,需要由ItemContainerGenrator
生成该项目(UI)的容器。生成在同一个(UI)线程上完成,因此您在添加项目后无法立即访问容器。
您可以订阅ResultsList.ItemContainerGenerator.StatusChanged
事件,并在事件处理程序中检查状态是否为GeneratorStatus.ContainersGenerated
,然后您就可以获取容器。
ResultsList.ItemContainerGenerator.StatusChanged += OnGeneratorStatusChanged;
...
private void OnGeneratorStatusChanged(object sender, EventArgs e)
{
if (MyListBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
// Access containers for newly added items
}
}
请参阅Dr.WPF的this article,其中详细说明了它的工作原理。