Windows アプリで GridView のスクロール位置を復元する必要があります。ScrollViewer.ScrollToHorizontalOffset() を呼び出して成功させる適切なタイミングを見つけようとしています。
OnNavigatedTo オーバーライドで呼び出しても効果はありません。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DataContext = LoadModel();
RestoreScrollPos();
}
ページの Loaded ハンドラーで呼び出しても効果はありません。
private void onPageLoaded(object sender, RoutedEventArgs e)
{
DataContext = LoadModel();
RestoreScrollPos();
}
次のようなことをするとうまくいきますが、GridView は最初にスクロール位置 0 で描画され、次に新しいスクロール位置にスナップされるため、耳障りです。
var dontAwaitHere =
Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
delegate()
{
RestoreScrollPos();
});
デフォルトのビジュアル スタジオ GridView プロジェクトからこの動作を再現しようとすると、ほとんどの場合は機能するように見えますが、一度も機能しないことがわかりました。ある種の競合状態があると思いますが、間違った場所に置いているのではないかと思います。
QUESTION = どこで RestoreScrollPos() を呼び出す必要がありますか? または、これをデバッグするにはどこを見ればよいですか?
private void RestoreScrollPos()
{
var scrollViewer = findScrollViewer(itemGridView);
if (scrollViewer != null)
{
scrollViewer.ScrollToHorizontalOffset(100000.0); // TODO test
}
}
public static ScrollViewer findScrollViewer(DependencyObject el)
{
ScrollViewer retValue = findDescendant<ScrollViewer>(el);
return retValue;
}
public static tType findDescendant<tType>(DependencyObject el)
where tType : DependencyObject
{
tType retValue = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(el);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(el, i);
if (child is tType)
{
retValue = (tType)child;
break;
}
retValue = findDescendant<tType>(child);
if (retValue != null)
{
break;
}
}
return retValue;
}