c# - 在正确的时间恢复 GridView 上的滚动位置

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

最佳答案

您应该仅在网格完成加载后调用 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);
}

关于c# - 在正确的时间恢复 GridView 上的滚动位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17081690/

相关文章:

c# - Windows Phone 8.1 - 尝试从相机胶卷获取缩略图时性能不佳

c# - 语言选择 : C++ or C# for Windows Store app?

windows-runtime - 如何在 WinRT 上重复使用弹出菜单

c# - 统一2D。无法从其他类(class)访问我的音频。

c# - 在代码合约中使用 Contract.ForAll

c# - winrt中的azure acs身份验证

c# - 使用给定文件夹中的源创建图像数组 C# Windows 桌面

c# - 来自 .mp4 的 channel 音频?

c# - 正则表达式:获取 id 列表

javascript - 将自定义 Cordova 插件转换为 Windows 8/RT