少し奇妙なもの。
Customer オブジェクトのリストが取り込まれている Treeview コントロールがあります。ツリーのどこかに特定のオブジェクトを見つけるための検索機能があり、次のようなコード行があります。
foreach (RbcUICustomer cust in tvQueue.Items)
{
var dataTVI = tvQueue.ItemContainerGenerator.ContainerFromItem(cust) as TreeViewItem;
ツリーは閉じた状態から始まり、検索の実行後にコードをステップ実行すると、ツリー全体が閉じられている場合、ツリー内の各顧客ノードに対して有効な TreeViewItem が返されます。それは問題ありません、そしてあなたが期待するものです。
問題は、最初にノードの 1 つを手動で開いてから検索を実行すると、上記の検索ループが展開されたノードに到達し、上記の 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が返されるような方法でツリーデータを無効にする可能性があることを誰かが提案できますか