我需要在我的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);
}