【问题标题】:Restore Scroll Position in LongListSelector after tombstone在墓碑后恢复 LongListSelector 中的滚动位置
【发布时间】:2011-06-13 06:33:35
【问题描述】:

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

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

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;

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

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 (我尝试过并且有效),但它是由比我聪明得多的人编写的,我想知道我是否不明白。 有没有更好的办法?

【问题讨论】:

    标签: windows-phone-7 silverlight-toolkit tombstoning


    【解决方案1】:

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

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

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

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

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

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

    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
    

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

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

    【讨论】:

      【解决方案2】:

      您可以尝试获取新列表中的项目吗?

      var _goodReference = myList.FirstOrDefault(x => x.id == _lastItem.Id);
      
      if (_goodReference != null)     
      Dispatcher.BeginInvoke(() => { myLongList.ScrollTo(_goodReference); }); 
      

      【讨论】:

      • 乍一看还不错。不幸的是 LongListSelector 中的项目有点复杂。列表源本质上是一个 List> 其中外部列表​​是分组(显示为组标题),内部列表是每个分组的项目。因此 _lastItem 变量可能包含一个项目,或者它可能包含一个 List,具体取决于当前滚动位置。
      • 你能把 List> 包装在一个具有某种自定义 id 的类中吗?
      • 是的。您可能正在使用可行的解决方案。我只是希望得到反馈,我只是错过了一些简单的东西。从墓碑中恢复似乎不必要地复杂。现在我需要根据最上面的可见项目是组标题还是项目来分别处理恢复。这不是火箭科学,但似乎可以通过像 ScrollTo(intPositionOffsetForTopmostVisibleItem) 这样简单的东西来改进它。
      猜你喜欢
      • 1970-01-01
      • 2013-01-14
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      相关资源
      最近更新 更多