2017-03-23 17 views
1

ListBoxItem内に含まれるチェックボックスのチェック状態を更新しようとしているときに奇妙な問題が発生しています。ListBoxItemを取得できません7番目の項目の後に、私はこれを動作させるためにいくつかの方法を試しました。 itemIndexたびに正の値を持っている(私はアイテムが発見されている知っている)んが、私はWPF ListBoxItemを項目別または7番目の項目の後のインデックスで取得できません

private IEnumerable<CheckBox> GetListBoxItemCheckBoxes(object item) 
{ 
    var itemIndex = LstItems.Items.IndexOf(item); 
    var selectedListBoxItem = LstItems.ItemContainerGenerator.ContainerFromIndex(itemIndex) as ListBoxItem; 
    var selectedListBoxItemCheckBoxes = selectedListBoxItem?.FindVisualChildrenOfType<CheckBox>(); 

    if (selectedListBoxItemCheckBoxes == null) 
    { 
     selectedListBoxItem = LstItems.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem; 
     selectedListBoxItemCheckBoxes = selectedListBoxItem?.FindVisualChildrenOfType<CheckBox>(); 

     if (selectedListBoxItemCheckBoxes == null) 
     { 
      itemIndex = LstItems.ItemContainerGenerator.Items.IndexOf(item); 
      selectedListBoxItem = LstItems.ItemContainerGenerator.ContainerFromIndex(itemIndex) as ListBoxItem; 
      selectedListBoxItemCheckBoxes = selectedListBoxItem?.FindVisualChildrenOfType<CheckBox>(); 
     } 
    } 

    return selectedListBoxItemCheckBoxes; 
} 

を知らないlistboxitemを得るカントなぜ私はこれがのタイミングで行うことがあり得ることだと思います私がその項目を追加した後でそれをやろうとしているときに、チェックボックスの状態を設定しようとしていますか?私はこの分野に関するいくつかの質問を読んだことがありますが、私の問題を手伝ってくれた人はいませんでした。私はこの答えが近いと思っていましたが、同じ結果をもたらしました:https://stackoverflow.com/a/23501378/1800140

アイテムはバインドされていませんが、ListBox.Items.Add(バインディングにあまり慣れていない)を使用して追加されます。

私はリストボックスの内容を定期的にリフレッシュする必要があり、そうするためにAPIコールを行う必要があるため、バックグラウンドスレッドでもこれを実行しています。

私のリストボックスの内容を更新するために使用されている方法は次のとおりです。 SetItemCheckedチェックボックスを取得するための最初のメソッドを呼び出しますが、しかし、これは

public void ResetAndAddItems<T>(IEnumerable<T> items, string displayByProperty = "", 
     Func<T, string> displayByFunc = null, 
     Dictionary<string, bool> checkedStates = null, 
     Func<ListItem<T>, Dictionary<string, bool>, bool> checkedStatesKeyFunc = null) 
{ 
    Dispatcher.Invoke(() => 
    { 
     LstItems.Items.Clear(); 
    }); 

    var listedItems = items?.ToList(); 

    if (listedItems == null || !listedItems.Any()) 
    { 
     return; 
    } 

    foreach (var item in listedItems) 
    { 
     var listItem = new ListItem<T> 
     { 
      DisplayByProperty = displayByProperty, 
      DisplayByFunc = displayByFunc, 
      Item = item 
     }; 

     Dispatcher.Invoke(() => 
     { 
      LstItems.Items.Add(listItem); 
      if (checkedStates != null && checkedStatesKeyFunc != null) 
      { 
       SetItemChecked(item, checkedStatesKeyFunc(item as ListItem<T>, checkedStates)); 
      } 
     }); 
    } 
} 

答えて

2

UIの仮想化は、リストボックスにデフォルトでTrueに設定されている第七項目の後にnullを返すために開始します。 UI仮想化が有効になっている場合、コンテナは表示されているアイテムに対してのみ作成されます。この添付プロパティを設定してみてください:

+0

これはパフォーマンス上の問題を引き起こす可能性がありますか? – Andy

+0

はい、ロード時間とメモリ消費量が増加します。ただし、これは、すべてのコンテナがすべてのListBoxItemに対して毎回使用可能であることを保証する唯一の方法です。あなたが成し遂げようとしていることを知ってもいいのですかあなたは本当にチェックボックスのインスタンスまたはチェックされた状態だけが必要ですか?後者の場合、データバインディングが解決策です。 – Hej

+0

チェックボックスをチェックして状態を確認しようとしましたが、バインディングを100%確信していないので、これを行うための唯一の方法はインスタンスを取得して自分で設定することです – Andy

0

この問題を解決するには、バインドする必要がありました。

問題は、一度に7つのアイテムだけがリストビューに表示されるため、これを回避するために、7番目のアイテムの後に次のアイテムにスクロールすることができますが、これは顕著に遅くなりました。

関連する問題