// 以前の回避方法だとまだ問題が発生することが分かったので、内容修正。
Windows Phone 用の Silverlight Toolkit (http://silverlight.codeplex.com/) に含まれる LongListSelector は、LongListSelector のインスタンスが含まれるページ (PhoneApplicationPage) から他のページに遷移した後にまた戻ってきたときに、内容が空になってしまうという不具合がある。この問題は、LongListSelector の ScrollTo() を使って強制的に再描画をトリガーすることで回避できる。
参考: WP7 LongListSelector? Be aware of its problems
http://mikaelkoskinen.net/post/wp7-longlist-selector-problems-and-fixing-them.aspx
ScrollTo() が不適当な場合は、ItemsSource の再設定でも再描画をかけることができる。ただし、他のページから戻ってきたとき、LongListSelector インスタンスのロードが終わる前に ItemsSource を設定すると、(既に ItemsSource が設定済みの場合) LongListSelector.Balance() メソッドが NullPointerException を投げてしまう。そのため、ItemsSource を再設定する場合は、LongListSelector の Loaded イベントのハンドラーでおこなう必要がある。
参考: LongListSelector NullReferenceException in Balance()
http://silverlight.codeplex.com/workitem/8376
// 2011/8/21:
// それでもまだLongListSelector.Balance()が問題を起こすようなので、
// LongListSelector.ItemsSourceの再設定は避けたほうがよさそう。
最終的には、対象となる LongListSelector インスタンスの Loaded イベントのハンドラーとして、次のようなメソッドを指定することになる。
// A "Loaded" event handler for LongListSelector.
private void RedrawLongListSelector(object sender, RoutedEventArgs e)
{
// LongListSelector has a bug where the content of it may
// become empty when we navigate back to a page which contains
// the LongListSelector instance.
//
// See http://mikaelkoskinen.net/post/wp7-longlist-selector-problems-and-fixing-them.aspx
//
// Therefore, we need to redraw it.
//
// The reason that redrawing must be written here in an event handler
// for Loaded is that LongListSelector throws a NullPointerException
// if ItemsSource is changed before it gets loaded (if ItemsSource
// has already been set).
//
// See http://silverlight.codeplex.com/workitem/8376
//
// 2011/8/21:
// Because LongListSelector still throws an exception, it seems better
// to avoid re-assigning data to LongListSelector.ItemsSource.
LongListSelector longListSelector = sender as LongListSelector;
if (longListSelector == null)
{
// This should not happen.
return;
}
if (longListSelector.Visibility == Visibility.Collapsed)
{
// The LongListSelector instance is hidden.
// No need to redraw it now.
return; }
// Get the current selected item.
var selectedItem = longListSelector.SelectedItem;if (selectedItem != null)
{
// Redraw the LongListSelector by scrolling to the item.
longListSelector.ScrollTo(selectedItem);return;
}
// Get items in the current view. An empty list may be returned
// if scrolling is happening too quickly. In addition, since the new
// Silverlight Toolkit for Windows Phone (2011 August), this
// method has been marked as obsolete and always returns an
// empty list, the document says.
var items = longListSelector.GetItemsInView();if (items != null && items.Count != 0)
{
// Redraw the LongListSelector by scrolling to the item.
longListSelector.ScrollingTo(items.ElementAt(0));return;
}
// No item in the current view. Nothing can be done.
return; // 2011/8/21:
// Removed the following code because it seems re-assigning
// data to LongListSelector.ItemsSource causes a problem
// in some contexts.
/*
// Get the current ItemsSource.
var itemsSource = longListSelector.ItemsSource;
if (itemsSource == null)
{
// No content. No need to redraw.
return;
}
// Set dummy data to force the LongListSelector to redraw itself.
longListSelector.ItemsSource = new ObservableCollection<object>();
// Assign the ItemsSource again.
longListSelector.ItemsSource = itemsSource;
*/ }