我需要在我的 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();
});
如果我尝试从默认的 Visual Studio GridView 项目中重现此行为,它似乎在大多数情况下都可以正常工作,但我确实看到它一次都不起作用。我相信存在某种竞争条件,我怀疑我把它放在错误的地方。
问题 = 我应该在哪里调用 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;
}