첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

▶ IItemGenerator.cs

namespace TestProject
{
    /// <summary>
    /// 항목 제너레이터 인터페이스
    /// </summary>
    /// <typeparam name="TItem">항목 타입</typeparam>
    public interface IItemGenerator<TItem>
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        #region 항목 수 - Count

        /// <summary>
        /// 항목 수
        /// </summary>
        int Count { get; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        #region 항목 생성하기 - CreateItem(index)

        /// <summary>
        /// 항목 생성하기
        /// </summary>
        /// <param name="index">인덱스</param>
        /// <returns>항목</returns>
        TItem CreateItem(int index);

        #endregion
    }
}

 

▶ VirtualList.cs

using System;
using System.Collections;
using System.Collections.Generic;

namespace TestProject
{
    /// <summary>
    /// 가상 리스트
    /// </summary>
    /// <typeparam name="TItem">항목 타입</typeparam>
    public class VirtualList<TItem> : IList<TItem>, IList where TItem : class
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Class
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 가상 열거자 - VirtualEnumerator

        /// <summary>
        /// 가상 열거자
        /// </summary>
        private class VirtualEnumerator : IEnumerator<TItem>
        {
            //////////////////////////////////////////////////////////////////////////////////////////////////// Field
            ////////////////////////////////////////////////////////////////////////////////////////// Private

            #region Field

            /// <summary>
            /// 가상 리스트
            /// </summary>
            private readonly VirtualList<TItem> virtualList;

            /// <summary>
            /// 현재 인덱스
            /// </summary>
            private int currentIndex;

            #endregion

            //////////////////////////////////////////////////////////////////////////////////////////////////// Property
            ////////////////////////////////////////////////////////////////////////////////////////// Public

            #region (IEnumerator<T>) 현재 항목 - Current

            /// <summary>
            /// 현재 항목
            /// </summary>
            public TItem Current
            {
                get
                {
                    return this.virtualList[this.currentIndex];
                }
            }

            #endregion

            #region (IEnumerator) 현재 항목 - IEnumerator.Current

            /// <summary>
            /// 현재 항목
            /// </summary>
            object IEnumerator.Current
            {
                get
                {
                    return Current;
                }
            }

            #endregion

            //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
            ////////////////////////////////////////////////////////////////////////////////////////// Public

            #region 생성자 - VirtualEnumerator(virtualList)

            /// <summary>
            /// 생성자
            /// </summary>
            /// <param name="virtualList">가상 리스트</param>
            public VirtualEnumerator(VirtualList<TItem> virtualList)
            {
                this.virtualList  = virtualList;
                this.currentIndex = 0;
            }

            #endregion

            //////////////////////////////////////////////////////////////////////////////////////////////////// Method
            ////////////////////////////////////////////////////////////////////////////////////////// Public

            #region (IEnumerator<T>) 다음 항목으로 이동하기 - MoveNext()

            /// <summary>
            /// 다음 항목으로 이동하기
            /// </summary>
            /// <returns>처리 결과</returns>
            public bool MoveNext()
            {
                if(this.currentIndex == this.virtualList.Count)
                {
                    return false;
                }

                ++this.currentIndex;

                return true;
            }

            #endregion
            #region (IEnumerator<T>) 리셋하기 - Reset()

            /// <summary>
            /// 리셋하기
            /// </summary>
            public void Reset()
            {
                this.currentIndex = 0;
            }

            #endregion
            #region (IEnumerator<T>) 리소스 해제하기 - Dispose()

            /// <summary>
            /// 리소스 해제하기
            /// </summary>
            public void Dispose()
            {
            }

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 항목 제너레이터
        /// </summary>
        private readonly IItemGenerator<TItem> itemGenerator;

        /// <summary>
        /// 캐시 항목 딕셔너리
        /// </summary>
        private readonly Dictionary<int, TItem> cacheItemDictionary;

        /// <summary>
        /// 항목 수
        /// </summary>
        private readonly int itemCount;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region (IList) 고정 크기 여부 - IsFixedSize

        /// <summary>
        /// 고정 크기 여부
        /// </summary>
        public bool IsFixedSize
        {
            get
            {
                return true;
            }
        }

        #endregion
        #region (IList) 인덱서 - IList.this[index]

        /// <summary>
        /// 인덱서
        /// </summary>
        /// <param name="index">인덱스</param>
        /// <returns>항목</returns>
        object IList.this[int index]
        {
            get
            {
                return this[index];
            }
            set
            {
                throw new NotSupportedException("VirtualList is a read-only collection.");
            }
        }

        #endregion

        #region (IList<T>) 인덱서 - this[index]

        /// <summary>
        /// 인덱서
        /// </summary>
        /// <param name="index">인덱스</param>
        /// <returns>항목</returns>
        public TItem this[int index]
        {
            get
            {
                if(!IsItemCached(index))
                {
                    CacheItem(index);
                }

                return this.cacheItemDictionary[index];
            }
            set
            {
                throw new NotSupportedException("VirtualList is a read-only collection.");
            }
        }

        #endregion

        #region (ICollection) 동기화 여부 - IsSynchronized

        /// <summary>
        /// 동기화 여부
        /// </summary>
        public bool IsSynchronized
        {
            get
            {
                return false;
            }
        }

        #endregion
        #region (ICollection) 동기 객체 - SyncRoot

        /// <summary>
        /// 동기 객체
        /// </summary>
        public object SyncRoot
        {
            get
            {
                return this;
            }
        }

        #endregion

        #region (ICollection<T>) 항목 수 - Count

        /// <summary>
        /// 항목 수
        /// </summary>
        public int Count
        {
            get
            {
                return this.itemCount;
            }
        }

        #endregion
        #region (ICollection<T>) 읽기 전용 여부 - IsReadOnly

        /// <summary>
        /// 읽기 전용 여부
        /// </summary>
        public bool IsReadOnly
        {
            get
            {
                return true;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - VirtualList(itemGenerator)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="itemGenerator">항목 제너레이터</param>
        public VirtualList(IItemGenerator<TItem> itemGenerator)
        {
            this.itemGenerator = itemGenerator;

            this.cacheItemDictionary = new Dictionary<int, TItem>();

            this.itemCount = this.itemGenerator.Count;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region (IList) 추가하기 - Add(value)

        /// <summary>
        /// 추가하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>인덱스</returns>
        public int Add(object value)
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (IList) 삽입하기 - Insert(index, value)

        /// <summary>
        /// 삽입하기
        /// </summary>
        /// <param name="index">인덱스</param>
        /// <param name="value">값</param>
        public void Insert(int index, object value)
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (IList) 제거하기 - Remove(value)

        /// <summary>
        /// 제거하기
        /// </summary>
        /// <param name="value">값</param>
        public void Remove(object value)
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (IList) 인덱스 구하기 - IndexOf(value)

        /// <summary>
        /// 인덱스 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>인덱스</returns>
        public int IndexOf(object value)
        {
            foreach(KeyValuePair<int, TItem> keyValuePair in this.cacheItemDictionary)
            {
                if(keyValuePair.Value.Equals(value))
                {
                    return keyValuePair.Key;
                }
            }

            return -1;
        }

        #endregion
        #region (IList) 포함 여부 구하기 - Contains(value)

        /// <summary>
        /// 포함 여부 구하기
        /// </summary>
        /// <param name="value">값</param>
        /// <returns>포함 여부</returns>
        public bool Contains(object value)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region (IList<T>) 삽입하기 - Insert(index, item)

        /// <summary>
        /// 삽입하기
        /// </summary>
        /// <param name="index">인덱스</param>
        /// <param name="item">항목</param>
        public void Insert(int index, TItem item)
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (IList<T>) 항목 제거하기 - RemoveAt(index)

        /// <summary>
        /// 항목 제거하기
        /// </summary>
        /// <param name="index">인덱스</param>
        public void RemoveAt(int index)
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (IList<T>) 인덱스 구하기 - IndexOf(item)

        /// <summary>
        /// 인덱스 구하기
        /// </summary>
        /// <param name="item">항목</param>
        /// <returns>인덱스</returns>
        public int IndexOf(TItem item)
        {
            return IndexOf(item);
        }

        #endregion

        #region (ICollection) 복사하기 - CopyTo(array, index)

        /// <summary>
        /// 복사하기
        /// </summary>
        /// <param name="array">배열</param>
        /// <param name="index">인덱스</param>
        public void CopyTo(Array array, int index)
        {
            int targetIndex = index;

            foreach(KeyValuePair<int, TItem> keyValuePair in this.cacheItemDictionary)
            {
                array.SetValue(keyValuePair.Value, targetIndex++);
            }
        }

        #endregion

        #region (ICollection<T>) 추가하기 - Add(item)

        /// <summary>
        /// 추가하기
        /// </summary>
        /// <param name="item">항목</param>
        public void Add(TItem item)
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (ICollection<T>) 제거하기 - Remove(item)

        /// <summary>
        /// 제거하기
        /// </summary>
        /// <param name="item">항목</param>
        /// <returns>처리 결과</returns>
        public bool Remove(TItem item)
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (ICollection<T>) 지우기 - Clear()

        /// <summary>
        /// 지우기
        /// </summary>
        public void Clear()
        {
            throw new NotSupportedException("VirtualList is a read-only collection.");
        }

        #endregion
        #region (ICollection<T>) 포함 여부 구하기 - Contains(item)

        /// <summary>
        /// 포함 여부 구하기
        /// </summary>
        /// <param name="item">항목</param>
        /// <returns>포함 여부</returns>
        public bool Contains(TItem item)
        {
            return (IndexOf(item) != -1);
        }

        #endregion
        #region (ICollection<T>) 복사하기 - CopyTo(array, index)

        /// <summary>
        /// 복사하기
        /// </summary>
        /// <param name="array">배열</param>
        /// <param name="index">인덱스</param>
        public void CopyTo(TItem[] array, int index)
        {
            this.cacheItemDictionary.Values.CopyTo(array, index);
        }

        #endregion

        #region (IEnumerable) 열거자 구하기 - IEnumerable.GetEnumerator()

        /// <summary>
        /// 열거자 구하기
        /// </summary>
        /// <returns>열거자</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return new VirtualEnumerator(this);
        }

        #endregion

        #region (IEnumerable<T>) 열거자 구하기 - GetEnumerator()

        /// <summary>
        /// 열거자 구하기
        /// </summary>
        /// <returns>열거자</returns>
        public IEnumerator<TItem> GetEnumerator()
        {
            return new VirtualEnumerator(this);
        }

        #endregion

        #region 항목 캐시하기 - CacheItem(index)

        /// <summary>
        /// 항목 캐시하기
        /// </summary>
        /// <param name="index">인덱스</param>
        public void CacheItem(int index)
        {
            this.cacheItemDictionary[index] = this.itemGenerator.CreateItem(index);
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 항목 캐시 여부 구하기 - IsItemCached(index)

        /// <summary>
        /// 항목 캐시 여부 구하기
        /// </summary>
        /// <param name="index">인덱스</param>
        /// <returns>항목 캐시 여부</returns>
        private bool IsItemCached(int index)
        {
            return this.cacheItemDictionary.ContainsKey(index);
        }

        #endregion
    }
}

 

▶ SampleItem.cs

namespace TestProject
{
    /// <summary>
    /// 샘플 항목
    /// </summary>
    public class SampleItem
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        public int Value01 { get; set; }
        public int Value02 { get; set; }
        public int Value03 { get; set; }
        public int Value04 { get; set; }
        public int Value05 { get; set; }
        public int Value06 { get; set; }
        public int Value07 { get; set; }
        public int Value08 { get; set; }
        public int Value09 { get; set; }
        public int Value10 { get; set; }

        public int Value11 { get; set; }
        public int Value12 { get; set; }
        public int Value13 { get; set; }
        public int Value14 { get; set; }
        public int Value15 { get; set; }
        public int Value16 { get; set; }
        public int Value17 { get; set; }
        public int Value18 { get; set; }
        public int Value19 { get; set; }
        public int Value20 { get; set; }

        public int Value21 { get; set; }
        public int Value22 { get; set; }
        public int Value23 { get; set; }
        public int Value24 { get; set; }
        public int Value25 { get; set; }
        public int Value26 { get; set; }
        public int Value27 { get; set; }
        public int Value28 { get; set; }
        public int Value29 { get; set; }
        public int Value30 { get; set; }

        public int Value31 { get; set; }
        public int Value32 { get; set; }
        public int Value33 { get; set; }
        public int Value34 { get; set; }
        public int Value35 { get; set; }
        public int Value36 { get; set; }
        public int Value37 { get; set; }
        public int Value38 { get; set; }
        public int Value39 { get; set; }
        public int Value40 { get; set; }

        public int Value41 { get; set; }
        public int Value42 { get; set; }
        public int Value43 { get; set; }
        public int Value44 { get; set; }
        public int Value45 { get; set; }
        public int Value46 { get; set; }
        public int Value47 { get; set; }
        public int Value48 { get; set; }
        public int Value49 { get; set; }
        public int Value50 { get; set; }
    }
}

 

▶ SampleItemGenerator.cs

namespace TestProject
{
    /// <summary>
    /// 샘플 항목 제너레이터
    /// </summary>
    public class SampleItemGenerator : IItemGenerator<SampleItem>
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 항목 수
        /// </summary>
        private readonly int count;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region (IItemGenerator<T>) 항목 수 - Count

        /// <summary>
        /// 항목 수
        /// </summary>
        public int Count
        {
            get
            {
                return this.count;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - SampleItemGenerator()

        /// <summary>
        /// 생성자
        /// </summary>
        public SampleItemGenerator()
        {
            this.count = 100000000; // 1억
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region (IItemGenerator<T>) 항목 생성하기 - CreateItem(index)

        /// <summary>
        /// 항목 생성하기
        /// </summary>
        /// <param name="index">인덱스</param>
        /// <returns>항목</returns>
        public SampleItem CreateItem(int index)
        {
            return new SampleItem
            {
                Value01 = index,
                Value02 = index,
                Value03 = index,
                Value04 = index,
                Value05 = index,
                Value06 = index,
                Value07 = index,
                Value08 = index,
                Value09 = index,
                Value10 = index,

                Value11 = index,
                Value12 = index,
                Value13 = index,
                Value14 = index,
                Value15 = index,
                Value16 = index,
                Value17 = index,
                Value18 = index,
                Value19 = index,
                Value20 = index,

                Value21 = index,
                Value22 = index,
                Value23 = index,
                Value24 = index,
                Value25 = index,
                Value26 = index,
                Value27 = index,
                Value28 = index,
                Value29 = index,
                Value30 = index,

                Value31 = index,
                Value32 = index,
                Value33 = index,
                Value34 = index,
                Value35 = index,
                Value36 = index,
                Value37 = index,
                Value38 = index,
                Value39 = index,
                Value40 = index,

                Value41 = index,
                Value42 = index,
                Value43 = index,
                Value44 = index,
                Value45 = index,
                Value46 = index,
                Value47 = index,
                Value48 = index,
                Value49 = index,
                Value50 = index,
            };
        }

        #endregion
    }
}

 

▶ MainForm.cs

using System.Windows.Forms;

using DevExpress.XtraGrid.Columns;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            this.gridView.OptionsView.ShowGroupPanel  = false;
            this.gridView.OptionsView.ColumnAutoWidth = false;

            VirtualList<SampleItem> list = new VirtualList<SampleItem>(new SampleItemGenerator());

            this.gridControl.DataSource = list;

            foreach(GridColumn column in this.gridView.Columns)
            {
                column.Width = 100;
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요