在适当的时间恢复GridView上的滚动位置



我需要在我的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项目中再现这种行为,它似乎大部分时间都在工作,但我确实看到它不工作一次。我相信有某种竞争条件,我怀疑我把它放在了错误的地方。

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;
    }

只有在网格加载完成后才能调用RestoreScrollPos:

public MyPageConstructor()
{
    this.InitializeComponent();
    this.itemGridView.Loaded += (s,e) => itemGridView_Loaded(s, e);
}
private void itemGridView_Loaded(object sender, RoutedEventArgs e)
{
    RestoreScrollPos();
}

至于在哪里加载数据,您应该尝试在LoadState:

protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
    DataContext = LoadModel();
    base.LoadState(navigationParameter, pageState);
}

最新更新