0

少し奇妙なもの。

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が返されるような方法でツリーデータを無効にする可能性があることを誰かが提案できますか

4

1 に答える 1

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

これがあなたのために働くことを願っています...

于 2012-10-12T17:19:02.093 に答える