2009-03-09 20 views
10

私は8列のユーザーデータを設定しているリストビューを持っています。ユーザーは、自動リフレッシュを有効にするオプションがあります。これにより、ListViewがクリアされ、データベースの最新データが再読み込みされます。WinForms ListView、リロード時にスクロールされた場所を記憶する

問題は、アイテムが消去されて再投入されると、表示領域がリストの先頭にジャンプすることです。だから私が2000年のアイテム1000を見ているなら、そのアイテムに戻るのはとても不便です。

基本的に、現在のスクロール距離(xとy)を取得して復元するにはどうすればよいですか?

答えて

4

以前は同じ問題がありましたが、モデルをリストと比較するアルゴリズムを実装してしまったので、変更された要素のみを追加/削除しました。このように、大規模な変更がなければ、リストは最初にジャンプしませんでした。そして、達成したい主なものは、効率性(リストが点滅しないように)でした。

+0

これは私がやったことです。最初のサブアイテムにタグを追加し、それを比較に使用し、必要なときにのみ更新しました。 – GenericTypeTea

1

ListView.TopItemプロパティを確認します。インデックスにはリスト内の位置が含まれている必要があります。新しいリストでそのインデックスを見つけ、そのアイテムにTopItemを設定すると、自動的にスクロールが行われます。

+0

ListView.TopItemが機能していないようです。並べ替えと何か関係があるかもしれないと思ったので、無効にしましたが、TopItemを項目に設定した直後にプロパティをチェックすると、変更されません(指定した項目ではなく別の項目に変更されます)。あなたは何か考えていますか? – TheAgent

0

残念ながら、ListViewの正確な位置までスクロールするためにinteropを使用する必要があります。既存のスクロール位置を取得するにはGetScrollInfo winapi関数を使用し、その位置にスクロールするにはSendMessageを使用します。

CodeProjectの記事にScrolling to a group with a ListViewという名前の記事があります。

12

私は必死にバギーListView.TopItemプロパティを使用しようとする人のためのいくつかの情報を提供したかった:

  1. あなたは
  2. リストビューの項目をListView.EndUpdateを呼び出した後TopItemプロパティを設定する必要がありますコントロールのTextプロパティがString.Empty以外の に設定されている必要があります。そうしないとプロパティが機能しません。
  3. ListView.TopItemを設定すると、null参照例外が断続的にスローされます。 Try ... Catchブロック内にこのコード行を常に保管してください。

もちろん、これにより、ListViewのスクロールバーが0にジャンプし、迷惑なトップアイテムの位置に戻ることがあります。この問題の回避策を見つけた場合は、この質問を更新してください。

+0

私は、TopItemに割り当てるときにオフ・バイ・ワンのエラーが出ることが分かりました(つまり、私が求めているものの上の項目にスクロールします)。バギー、あなたは言う? :-) – RichieHindle

0

私は同じ問題を抱えていました。私は、1/2秒ごとに値を設定するリストビューを持っています。そして、インデックスが表示アイテムであるListItemにTopItemを設定すると、リストはtopItemと2つのポイントの間でジャンプしました。

したがって、この問題を解決するために、EndUpdateの呼び出し後にTopItermを設定します。

lvB.EndUpdate(); 
lvI.EndUpdate(); 
lvR.EndUpdate(); 

if (lstEntryInts.Items.Count > 0) 
    lstEntryInts.TopItem = lstEntryInts.Items[iTopVisIdx]; 
if (lstEntryBools.Items.Count > 0) 
    lstEntryBools.TopItem = lstEntryBools.Items[iTopVisIdx]; 
if (lstEntryReals.Items.Count > 0) 
    lstEntryReals.TopItem = lstEntryReals.Items[iTopVisIdx];​ 
0

維持スクロール位置に対する私のソリューション:

フォームレベルの変数:

scrollSpot = this.listView1.TopItem.Index; 
refreshTheForm(); 
:リストビューのリフレッシュ(すなわちタイマー、ボタン)現在のスポットを格納するための内部

private static int scrollSpot = 0; 

保存されたスポットを表示するrefreshTheFormメソッド(メソッドの最後に配置):

if (scrollSpot <= 1) 
{ 
    listView1.Items[scrollSpot].Selected = true; 
} 
else 
{ 
    listView1.Items[scrollSpot - 2].Selected = true; 
} 
listView1.TopItem = listView1.SelectedItems[0]; 
3

ListViewのTopItemIndexプロパティはあなたが探しているものですが、VS2010リリースで対処されているはずの確認されたバグがあります。

とにかく、この作品を作るための私の回避策はこれを行うことです。

listViewOutput.TopItemIndex = outputList.Count - 1; 
listViewOutput.TopItemIndex = myNewTopItemIndex; 

何らかの理由でそれが直接それを更新しますが、最後の項目に設定すると、私はしたい1が確実に動作しない設定私のために。私は成功し、次の使用

6

私のテストでは
int topItemIndex = 0; 
try 
{ 
    topItemIndex = listView1.TopItem.Index; 
} 
catch (Exception ex) 
{ } 
listView1.BeginUpdate(); 
listView1.Items.Clear(); 
//CODE TO FILL LISTVIEW GOES HERE 
listView1.EndUpdate(); 
try 
{ 
    listView1.TopItem = listView1.Items[topItemIndex]; 
} 
catch (Exception ex) 
{ } 
0

を私は選択した項目を保存するためにint型を使用しますが、あなたも、TopItemを必要としませんでした。また、ViewItileまたはView.LargeIconを使用している場合、TopItemは例外をスローします。

このコードは、スクロールバーを移動しません:

listView1.BeginUpdate(); 
listView1.Items.Clear(); 

// loop through your add routine 
listView1.Items.Add(lvi); 

listView1.EndUpdate(); 
関連する問題