我需要在我的 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;
}
最佳答案
您应该仅在网格完成加载后调用 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/