ItemContainerGenerator#ContainerFromItem で表示済みの項目を確実に取得する方法

画面に表示されている項目でも、ItemContainerGenerator#ContainerFromItem でnullを返す場合があります。

たとえば、ItemsSourceに設定してすぐのタイミングなど。

Dispatcher.BeginInvokeなどで取得タイミングをずらすことによって回避できる場合もありますが、UpdateLayoutを使った方が確実なようです。

 

実際、ListBoxでItemsSource設定後にDispatcher.BeginInvokeでタイミングずらして取得しようとした場合、取れたり取れなかったりといった状況でした。(今回はSilverlightでしたが、WEBの情報見る限りだとWPFでも同じようです)

それを下記のようにUpdateLayout後に呼び出すようにしたことにより、Dispatcher.BeginInvokeも不要で、確実に取得できるようになりました。

listBox.UpdateLayout();
ListBoxItem listBoxItem = listBox.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem;

if (listBoxItem != null)
{
    listBoxItem.Focus();
}