[DEVEXPRESS/WINFORM] GridControl 클래스 : 대용량 데이터 바인딩하기 (캐시 객체 Dictionary 사용시)
DevExpress/WinForm 2020. 1. 18. 14:28728x90
반응형
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
반응형
그리드형(광고전용)
댓글을 달아 주세요