有点奇怪。
我有一个 Treeview 控件,该控件正在填充客户对象列表。有一个搜索功能可以在树中的某处找到某个对象,其中有一行代码如下。
foreach (RbcUICustomer cust in tvQueue.Items)
{
var dataTVI = tvQueue.ItemContainerGenerator.ContainerFromItem(cust) as TreeViewItem;
树开始关闭,如果您在执行搜索后单步执行代码,如果整个树都关闭,这将为树中的每个客户节点返回一个有效的 TreeViewItem。这很好,你会期待什么。
问题是,如果您先手动打开其中一个节点,然后执行搜索,则上面的搜索循环会到达展开的节点,并且上面的 ItemContainerGenerator 方法返回 null,因此它找不到该项目的容器。
我认为问题与手动扩展节点时我对基础数据所做的操作有关,这在某种程度上会改变它并且不能正确刷新它。扩展节点背后的商业理念是,它从服务层获取客户的客户帐户列表,并以编程方式将它们可视化地添加到树中,然后将节点扩展。但是通过这样做,似乎阻止了上面的代码行能够找到并返回有效的容器。
更新客户的代码有点复杂,但我将在下面粘贴精华。_customerList 是用于保存数据的类数组。
ExpandNode(TreeViewItem item)
{
var cust = item.Header as Customer;
var task = new Task(() => RunBackgroundThreadToAddAccounts(Customer));
task.Start();
}
RunBackgroundThreadToAddAccoutns(Customer)
{
for (var i = 0; i < _customerList.Count; i++)
{
var customer = _customerList[i];
if (customer.CustomerId == cust.CustomerId)
{
customer.Accounts.Clear();
customer.Accounts.Add(LoadingAccount);
_customerList[i] = customer;
UpdateCustomerCompleted(item, i);
break;
}
}
}
private void UpdateCustomerCompleted(TreeViewItem item, int positionIndex)
{
var customer = _customerList[positionIndex];
GUIHelper.Invoke(() => item.Header = customer);
if (customer.Accounts.Count == 0)
{
customer.Accounts.Add(EmptyAccount);
}
GUIHelper.Invoke(() => item.ItemsSource = customer.Accounts);
GUIHelper.Invoke(() => _treeSelectionHandler.ChangeSelectedState(item));
GUIHelper.Invoke(() => item.Items.Refresh());
GUIHelper.Invoke(item.UpdateLayout);
}
谁能建议上述扩展节点的代码可能会使树数据无效,以至于当我尝试为其检索容器时,它返回null?