5

WP7 Silverlight Toolkit の 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;

次に、ユーザーがページに戻ったときに、2 つの値 (状態または変数) のいずれかを確認し、それを使用して最後のスクロール位置を復元します。

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 を上書きしただけで、明らかにデフォルトの == は (設計上) 参照を比較します。廃棄後に State アイテムを復元すると、参照が一致しません。== を上書きすることはできますが、それは間違っているように感じます。代わりに equals を呼び出すようにコントロール ソースを変更して再構築することはできますが (試してみたところ、うまくいきました)、それは私よりもずっと賢い人によって書かれたものであり、私はそれを理解できないのではないかと思っています。

4

2 に答える 2

2

これは私が思いついた修正です...

Toolkit のソース コードは自由に利用できるので、LongListSelector ソース コードを編集して、== の代わりに .Equals を呼び出すことにしました。私のユースケースでは適切に機能しているようで、他の誰かが役に立つと思った場合に備えて共有したいと思いました...

LongListSelector.cs で GetFlattenedIndex(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

置き換えは、使用しているツールキットのダウンロードに依存することに注意してください!

コントロールにこれらの変更を加えると、LongListSelector に表示されるすべてのオブジェクト タイプの Equals を適切にオーバーライドする限り、参照が等しくなくても、ScrollTo(object) で指定されたオブジェクトが適切に一致します。グループ化されたリストがある場合、これはアイテム クラスだけでなく、グループ化クラスにも適用されることを忘れないでください。

于 2011-07-31T21:11:54.447 に答える
0

新しいリストの項目を取得してみていただけますか?

var _goodReference = myList.FirstOrDefault(x => x.id == _lastItem.Id);

if (_goodReference != null)     
Dispatcher.BeginInvoke(() => { myLongList.ScrollTo(_goodReference); }); 
于 2011-06-15T01:01:19.883 に答える