본문 바로가기
프로그래밍

[C#] ListView VirtualMode 예제

by 건우아빠유리남편 2011. 2. 25.
반응형

[C#] ListView VirtualMode 예제

속도의 차이가 정말 엄청나다... 기냥 for문으로 Add하는거랑 엄청난 차이... 꼭 익혀야할 VirtualMode

http://msdn.microsoft.com/ko-kr/library/system.windows.forms.datagridview.virtualmode.aspx
http://msdn.microsoft.com/ko-kr/library/system.windows.forms.listview.virtualmode(VS.90).aspx

-List View 설명-

VirtualMode 속성을 true로 설정하면 ListView가 가상 모드가 됩니다. 가상 모드에서는 일반적인 Items 컬렉션이 사용되지 않습니다. 대신 ListView에서 요청할 때 ListViewItem 개체가 동적으로 만들어집니다.

가상 모드는 여러 가지 상황에서 유용할 수 있습니다. 이미 메모리에 있는 대규모 컬렉션을 사용하여 ListView 개체를 채워야 하는 경우 각 항목에 대한 ListViewItem 개체를 만드는 방법은 지나치게 소모적일 수 있습니다. 가상 모드에서는 필요한 항목만 만들어집니다. ListViewItem 개체의 값을 자주 다시 계산해야 하는 경우도 있습니다. 전체 컬렉션에 대해 이를 수행하면 성능이 크게 저하됩니다. 가상 모드에서는 필요한 항목만 계산됩니다.

가상 모드를 사용하려면 ListView에서 항목을 요청할 때마다 발생하는 RetrieveVirtualItem 이벤트를 처리해야 합니다. 이 이벤트 처리기에서는 지정된 인덱스에 속하는 ListViewItem 개체를 만들어야 합니다. 또한 VirtualListSize 속성을 가상 목록의 크기로 설정해야 합니다.

SearchForVirtualItem 이벤트를 처리하면 가상 모드에서 검색을 수행할 수 있습니다. 이 이벤트를 처리하지 않으면 FindItemWithTextFindNearestItem 메서드에서 nullNothingnullptrNull 참조(Visual Basic의 경우 Nothing)을 반환합니다.

ListViewItem 개체의 캐시를 유지하기 위해 CacheVirtualItems 이벤트를 처리할 수 있습니다. 계산 또는 조회로 인해 ListViewItem 개체가 만들어져 리소스가 많이 소모되는 경우 캐시를 유지하면 성능이 향상됩니다.

View 속성이 Tile로 설정되어 있는 경우 VirtualModetrue로 설정되어 있으면 값이 LargeIcon으로 자동 변경됩니다.

가상 모드에서는 Items 컬렉션이 사용되지 않습니다. 이 컬렉션에 액세스하려고 하면 InvalidOperationException이 발생합니다. CheckedItems 컬렉션 및 SelectedItems 컬렉션의 경우도 마찬가지입니다. 선택되거나 확인된 항목을 검색하려면 SelectedIndicesCheckedIndices 컬렉션을 대신 사용합니다.




testVirtualMode.zip



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace testVirtualMode
{
    public partial class Form1 : Form
    {
        private ListViewItem[] myCache; //array to cache items for the virtual list
        private int firstItem; //stores the index of the first item in the cache

        public Form1()
        {
            InitializeComponent();

            //Create a simple ListView.
            ListView listView1 = new ListView();
            listView1.View = View.Details;
            listView1.VirtualMode = true;
            listView1.VirtualListSize = 1000000;
            listView1.Dock = DockStyle.Fill;
            listView1.Columns.Add("column1");

            //Hook up handlers for VirtualMode events.
            listView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
            listView1.CacheVirtualItems += new CacheVirtualItemsEventHandler(listView1_CacheVirtualItems);
            listView1.SearchForVirtualItem += new SearchForVirtualItemEventHandler(listView1_SearchForVirtualItem);

            //Add ListView to the form.
            this.Controls.Add(listView1);

            //Search for a particular virtual item.
            //Notice that we never manually populate the collection!
            //If you leave out the SearchForVirtualItem handler, this will return null.
            //ListViewItem lvi = listView1.FindItemWithText("111111");

            //Select the item found and scroll it into view.
            //if (lvi != null)
            //{
            //    listView1.SelectedIndices.Add(lvi.Index);
            //    listView1.EnsureVisible(lvi.Index);
            //}

        }

        //The basic VirtualMode function.  Dynamically returns a ListViewItem
        //with the required properties; in this case, the square of the index.
        private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            //Caching is not required but improves performance on large sets.
            //To leave out caching, don't connect the CacheVirtualItems event
            //and make sure myCache is null.

            //check to see if the requested item is currently in the cache
            if (myCache != null && e.ItemIndex >= firstItem && e.ItemIndex < firstItem + myCache.Length)
            {
                //A cache hit, so get the ListViewItem from the cache instead of making a new one.
                e.Item = myCache[e.ItemIndex - firstItem];
            }
            else
            {
                //A cache miss, so create a new ListViewItem and pass it back.
                int x = e.ItemIndex;
                e.Item = new ListViewItem(x.ToString());
            }
        }

        //Manages the cache.  ListView calls this when it might need a
        //cache refresh.
        private void listView1_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
        {
            //We've gotten a request to refresh the cache.
            //First check if it's really neccesary.
            if (myCache != null && e.StartIndex >= firstItem && e.EndIndex <= firstItem + myCache.Length)
            {
                //If the newly requested cache is a subset of the old cache,
                //no need to rebuild everything, so do nothing.
                return;
            }

            //Now we need to rebuild the cache.
            firstItem = e.StartIndex;
            int length = e.EndIndex - e.StartIndex + 1; //indexes are inclusive
            myCache = new ListViewItem[length];

            //Fill the cache with the appropriate ListViewItems.
            int x = 0;
            for (int i = 0; i < length; i++)
            {
                x = i + firstItem;
                myCache[i] = new ListViewItem(x.ToString());
            }

        }

        //This event handler enables search functionality, and is called
        //for every search request when in Virtual mode.
        private void listView1_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)
        {
            //We've gotten a search request.
            //In this example, finding the item is easy since it's
            //just the square of its index.  We'll take the square root
            //and round.
            double x = 0;
            if (Double.TryParse(e.Text, out x)) //check if this is a valid search
            {
                x = Math.Sqrt(x);
                x = Math.Round(x);
                e.Index = (int)x;

            }
            //If e.Index is not set, the search returns null.
            //Note that this only handles simple searches over the entire
            //list, ignoring any other settings.  Handling Direction, StartIndex,
            //and the other properties of SearchForVirtualItemEventArgs is up
            //to this handler.
        }

    }
}



반응형

댓글