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

时间:2013-06-13 07:39:19

标签: c# windows-8 windows-runtime windows-store-apps

我需要在Windows应用中恢复GridView的滚动位置。我正在努力找到合适的时间来调用ScrollViewer.ScrollToHorizo​​ntalOffset()并让它成功。

如果我在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;
    }

1 个答案:

答案 0 :(得分:0)

只有在网格加载后才能调用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);
}