2

Winformsアプリの仮想ListViewコントロールに関して、RetrieveVirtualItemイベントのすべての機能は何ですか?

シナリオ:ListViewキャッシュとして機能するDictionaryオブジェクトがあります。そして、そのアイテムはListViewに表示されます。列をクリックすると、キャッシュディクショナリがメモリ内でソートされ、ListViewがRefresh()されます。UIへの影響、ListViewは適切にソートされています。:)

しかし、Refresh()でトリガーされるRetrieveVirtualItemイベントの役割を理解したいと思います。

RetrieveVirtualItemイベントハンドラー[他の誰かのコード:(]で、次のことが行われます。

  1. に基づいてRetrieveVirtualItemEventArgs.ItemIndex、キャッシュからメッセージを取得します
  2. セットRetrieveVirtualItemEventArgs.Item=上記の取得アイテム

イベントハンドラーで何が行われるかが重要なようです。それを取り出すと、ListViewが泣くからです。このイベントの意義は何ですか?

編集 または質問を言い換えさせてください...私の懸念は、なぜ、並べ替え(およびRetrieveVirtualItemイベントハンドラー)の後、選択されたアイテムが並べ替え前の場所に残るのかということです。つまり、アイテム#5を選択して並べ替え、並べ替えによってこのアイテムが最後のアイテムになる場合は、並べ替えの後に最後のアイテムを選択することをお勧めします。しかし、私の場合、ソート後に5番目のアイテムが選択されます。RetrieveVirtualItemでは、 WRTで選択されたアイテムのデフォルトの動作は何ですか?

4

3 に答える 3

4

仮想ListViewは、現在画面に表示されている行に対してのみRetreiveVirtualItemを呼び出す必要があります。

たとえば、ListView内を移動すると、Page Downキーを押すと、ListViewは一番上の行のインデックスになるはずのものを計算し、RetrieveVirtualItemを呼び出して、コードが各行のインデックスで使用するアイテムを提供できるようにします。 。

提供しているアイテムをRetrieveVirtualItemを介してキャッシュまたは保存しない限り、リストビューからスクロールアウトすると、アイテムは存在しなくなります。

これは、VirtualListViewの仮想の意味です。実際の行はなく、行は仮想です。これにより、数十万行を含むリストを表示できます。これは、画面に表示される行の数だけが実際に含まれるためです。

実際、ListViewは、データの内部リストを上下に移動するウィンドウのようなものです。RetreiveVirtualItemメソッドは、アイテムが移動するときにそのウィンドウにアイテムを移動するために呼び出すものです。15行目に移動しました。その行のアイテムを教えてください。表示される各行インデックスに対してRetreiveVirtualItemの呼び出しに進みます。ListViewが画面上で5行の高さである場合、ListViewを裏付ける実際のデータに3000個のアイテムがあったとしても、RetrieveVirtualItemへの呼び出しは5回受信されます。ListViewの一番上の行が変更されるたびに(ナビゲーションのため)、RetrieveVirtualItemへの呼び出しが5回受信されます(これは常に当てはまるわけではありませんが、正しい考えです。たとえば、1行下にスクロールすると、

ListViewをデータのリストの上下に移動すると、ListViewがディスプレイ上で1行だけの高さであると仮定すると(つまり、実際には1行だけが画面に表示される)、説明がさらに簡単になると思います(つまり、ユーザーはListViewをナビゲートします)、新しい行に移動するたびに、RetrieveVirtualItemを1回だけ呼び出します。

お役に立てば幸いです...幸運を祈ります

于 2012-12-10T22:28:32.417 に答える
2

RetrieveVirtualItemイベントは、ListViewが仮想モードになっている場合にのみ使用されます。(仮想モードでない場合のように)ListViewItemsをItemsコレクションに保持するのではなく、必要に応じてListViewItemsを動的に作成します。

RetrieveVirtualItemイベントを処理しない場合、ListViewItemsはListViewに追加されません。イベントを処理するために記述された典型的なメソッドのサンプルコードをいくつか添付しました。

  //Dynamically returns a ListViewItem with the required properties; in this case, the square of the index.
void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
    {
        //Check if cache has been instantiated yet, and if so, whether the item corresponding to the index requested has been added to the cache already
        if (myCache != null && e.ItemIndex >= firstItem && e.ItemIndex < firstItem + myCache.Length)
        {
            //Return cached item for index
            e.Item = myCache[e.ItemIndex - firstItem];
        }
        else
        {
            //When item not in cache (or cache not available) return a new ListViewItem
            int x = e.ItemIndex * e.ItemIndex;
            e.Item = new ListViewItem(x.ToString());
        }
    }

この例は、MSDN(http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode (v=vs.90).aspx )から抜粋したもので、詳細を確認できます。

于 2012-05-09T09:23:45.670 に答える
2

仮想リストビューはインデックスのみを扱います。したがって、ソート前に5番目のアイテムが選択された場合でも、ソート後も5番目のアイテムが選択されます。コントロール自体には、以前は5行目にあったデータが現在は1行目にあることを知る方法がありません。

並べ替え方法で自分でプログラムする必要があります。

  1. SelectedItems選択されたアイテムを覚えておいてください(覚えておいてください:仮想モードではプロパティを使用できません)
  2. 並べ替えを行う
  3. 以前に選択したアイテムのインデックスが現在ライブになっていることを確認します
  4. それらのインデックスを選択してください

これらすべての動作は、標準の.NETListViewのラッパーであるObjectListViewで確認できます。

于 2012-05-11T05:59:52.727 に答える