在墓碑后恢复 LongListSelector 中的滚动位置 [英] Restore Scroll Position in LongListSelector after tombstone

查看:23
本文介绍了在墓碑后恢复 LongListSelector 中的滚动位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 WP7 Silverlight 工具包中的 LongListSelector 控件.这需要一些工作,但我终于让它与我的应用程序一起使用.不幸的是,我在正确处理墓碑处理过程中遇到了一些麻烦.

I'm trying to work with the LongListSelector control from the WP7 Silverlight Toolkit. It's taken a bit of work, but I finally have it working with my app. Unfortunately, I am having some trouble properly handling the tombstoning process.

当应用程序墓碑(或用户通过选择列表中的项目导航到另一个页面)时,我保存列表中最顶部可见项目的副本.我将它同时保存到类变量和应用状态集合中.

When the application tombstones (or the user navigates to another page by selecting an item in the list), I save a copy of the topmost visible item in the list. I save it to both a class variable and to the app state collection.

ICollection<object> visibleItems = myLongList.GetItemsInView();
_lastItem = null;
if (visibleItems.Count > 0)
    _lastItem = visibleItems.First();
IDictionary<string, object> state = 
              Microsoft.Phone.Shell.PhoneApplicationService.Current.State;
state["IndexByName_LastTopItem"] = _lastItem;

然后,当用户返回页面时,我会检查两个值之一(状态或变量)并使用它来恢复最后的滚动位置.

Then, when the user returns to the page I check for one of the two values (state or variable) and use it to restore the last scroll position.

if (_lastItem == null) 
{ 
    if (state.ContainsKey("IndexByName_LastTopItem")) 
    { 
        _lastItem = state["IndexByName_LastTopItem"] as Chemical; 
    } 
} 

if (_lastItem != null) 
    Dispatcher.BeginInvoke(() => { myLongList.ScrollTo(_lastItem); }); 

除非应用程序墓碑,否则这很好用.在这种情况下,我不会收到任何错误,但是在我触摸并拖动之前,该列表是完全空白的.一旦我这样做了,它就会重新显示在列表的顶部.我查看了控件的源代码,发现当您调用 .ScrollTo(object) 时,它没有匹配.进一步调查发现,在搜索要滚动到的项目时,它使用 == 而不是 Equals 进行比较.我只覆盖了 Equals,显然默认 == 比较(按设计)引用.当您在逻辑删除后恢复状态项时,引用不匹配.我可以覆盖 ==,但这感觉不对.我可以更改和重建控制源以调用 equals(我尝试过并且有效),但它是由比我聪明得多的人编写的,我想知道我是否只是不明白.有没有更好的办法?

This works great unless the application tombstones. In that case I don't get any errors, but the list is completely blank until I touch it and drag. Once I do that, it redisplays at the top of the list. I took a look at the source for the control and found that when you call .ScrollTo(object) it doesn't get a match. Further investigation identified that when searching for an item to scroll to, it compares using == instead of Equals. I only overrode Equals, and apparently the default == compares (by design) references. When you restore a State item after tombstoning the references don't match. I can override ==, but that feels wrong. I can change and rebuild the control source to call equals instead (I tried and it worked), but it was written by people much smarter than I and I'm wondering if I just don't get it. Is there a better way?

推荐答案

这是我最终想出的解决方案...

This is the fix I ended up coming up with...

由于源代码可免费用于 Toolkit,我最终编辑了 LongListSelector 源代码以调用 .Equals 而不是 ==.它似乎适用于我的用例,我想我会分享以防其他人发现它有用...

Since the source code is freely available for the Toolkit, I ended up editing the LongListSelector source code to call .Equals instead of ==. It seems to work properly for my use case and I thought I'd share in case anyone else finds it useful...

在 LongListSelector.cs 中找到 GetFlattenedIndex(object item) 函数并替换

in LongListSelector.cs find the GetFlattenedIndex(object item) function and replace

if (item == _flattenedItems[index].Item)

if (item.Equals(_flattenedItems[index].Item))

然后在同一个文件中找到 GetResolvedIndex(object item, out ContentPresenter contentPresenter) 函数并替换

and then in the same file find the GetResolvedIndex(object item, out ContentPresenter contentPresenter) function and replace

if (node.Value.Content == item)  // Nov 2010 Release
// OR
if (_flattenedItems[index].Item == item)  // Feb 2011 Release

if (item.Equals(node.Value.Content))  // Nov 2010 Release
// OR
if (item.Equals(_flattenedItems[index].Item))  // Feb 2011 Release

请注意,替换取决于您使用的工具包下载!

NOTE that the replace depends on which toolkit download you are using!

一旦您对控件进行了这些更改,它就会正确匹配 ScrollTo(object) 中指定的对象,即使引用不相等,只要您正确覆盖 LongListSelector 中显示的所有对象类型的 Equals.如果您有分组列表,请不要忘记这适用于您的分组类以及您的项目类!

Once you have made these changes to the control, it will properly match up objects specified in ScrollTo(object), even if the references are not equal as long as you properly override Equals for all object types displayed in your LongListSelector. Don't forget this applies to your Grouping class as well as your item class if you have a grouped list!

这篇关于在墓碑后恢复 LongListSelector 中的滚动位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆