有点奇怪。
我有一个Treeview控件,正在填充Customer对象列表。有一个搜索功能可以在树中的某个位置查找某个对象,该对象的代码行如下所示。
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?
答案 0 :(得分:0)
我不太了解您的代码,例如:
RunBackgroundThreadToAddAccoutns(Customer)
{
for (var ...
这里的参数是什么,类型是什么?
但我认为问题可能是当您设置item.ItemsSource = customer.Accounts
时,您将旧项目源更改为此新项目,而不是之前的树项目。
无论如何,如果您在WPF中使用树,我建议您查看这些参考资料,这对您非常有帮助:
http://www.codeproject.com/Articles/17025/Custom-TreeView-Layout-in-WPF
http://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode
希望这对你有用......