■ ObservableCollection 가상 소스 만들기 예제

----------------------------------------------------------------------------------------------------

using System.Collections.ObjectModel;

 

...

 

/// <summary>

/// 샘플 데이터

/// </summary>

public class SampleData

{

    //////////////////////////////////////////////////////////////////////////////////////////////////// Property

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 항목 1 - 항목1

 

    /// <summary>

    /// 항목 1

    /// </summary>

    public string 항목1 { get; set; }

 

    #endregion

 

    #region 항목 2 - 항목2

 

    /// <summary>

    /// 항목 2

    /// </summary>

    public string 항목2 { get; set; }

 

    #endregion

 

    #region 항목 3 - 항목3

 

    /// <summary>

    /// 항목 3

    /// </summary>

    public string 항목3 { get; set; }

 

    #endregion

 

    #region 항목 4 - 항목4

 

    /// <summary>

    /// 항목 4

    /// </summary>

    public string 항목4 { get; set; }

 

    #endregion

 

    #region 항목 5 - 항목5

 

    /// <summary>

    /// 항목 5

    /// </summary>

    public string 항목5 { get; set; }

 

    #endregion

}

 

...

 

#region 샘플 컬렉션 구하기 - GetSampleCollection()

 

/// <summary>

/// 샘플 컬렉션 구하기

/// </summary>

/// <returns>샘플 컬렉션 구하기</returns>

private ObservableCollection<object> GetSampleCollection()

{

    ObservableCollection<object> collection = new ObservableCollection<object>();

 

    for(int i = 0; i < 1000000; i++)

    {

        collection.Add

        (

            new SampleData()

            {

                항목1 = "값 " + i.ToString(),

                항목2 = "값 " + i.ToString(),

                항목3 = "값 " + i.ToString(),

                항목4 = "값 " + i.ToString(),

                항목5 = "값 " + i.ToString()

            }

        );

    }

 

    return collection;

}

 

#endregion

 

...

 

ObservableCollectionVirtualSource virtualSource = new ObservableCollectionVirtualSource(GetSampleCollection());

 

...

 

this.gridControl.DataSource = virtualSource;

----------------------------------------------------------------------------------------------------

※ gridControl 객체는 가상 모드를 지원하는 그리드 컨트롤로 가정한다.

 

■ ObservableCollection 가상 소스 만들기

----------------------------------------------------------------------------------------------------

ObservableCollectionVirtualSource.cs

 

 

using System;

using System.Collections;

using System.Collections.ObjectModel;

using System.ComponentModel;

 

/// <summary>

/// 관측 가능 컬렉션 가상 소스

/// </summary>

public class ObservableCollectionVirtualSource : IList, ITypedList

{

    //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

    #region Field

 

    /// <summary>

    /// 소스 컬렉션

    /// </summary>

    private ObservableCollection<object> sourceCollection;

 

    /// <summary>

    /// 로우 카운트

    /// </summary>

    private int rowCount;

 

    /// <summary>

    /// 컬럼 카운트

    /// </summary>

    private int columnCount;

 

    /// <summary>

    /// 속성 설명자 컬렉션

    /// </summary>

    private PropertyDescriptorCollection propertyDescriptorCollection;

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Property

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 컬렉션 - SourceCollection

 

    /// <summary>

    /// 컬렉션

    /// </summary>

    public ObservableCollection<object> SourceCollection

    {

        get

        {

            return this.sourceCollection;

        }

    }

 

    #endregion

 

    #region 로우 카운트 - RowCount

 

    /// <summary>

    /// 로우 카운트

    /// </summary>

    public int RowCount

    {

        get

        {

            return this.rowCount;

        }

        set

        {

            if(value < 1)

            {

                value = 0;

            }

 

            if(this.rowCount == value)

            {

                return;

            }

 

            this.rowCount = value;

        }

    }

 

    #endregion

 

    #region 컬럼 카운트 - ColumnCount

 

    /// <summary>

    /// 컬럼 카운트

    /// </summary>

    public int ColumnCount

    {

        get

        {

            return this.columnCount;

        }

        set

        {

            if(value < 1)

            {

                value = 0;

            }

 

            if(this.columnCount == value)

            {

                return;

            }

 

            this.columnCount = value;

 

            SetPropertyDescriptorCollection();

        }

    }

 

    #endregion

 

    // IList

    #region 카운트 - Count

 

    /// <summary>

    /// 카운트

    /// </summary>

    public virtual int Count

    {

        get

        {

            return this.rowCount;

        }

    }

 

    #endregion

 

    // IList

    #region 동기화 여부 - IsSynchronized

 

    /// <summary>

    /// 동기화 여부

    /// </summary>

    public virtual bool IsSynchronized

    {

        get

        {

            return true;

        }

    }

 

    #endregion

 

    // IList

    #region 동기 루트 - SyncRoot

 

    /// <summary>

    /// 동기 루트

    /// </summary>

    public virtual object SyncRoot

    {

        get

        {

            return true;

        }

    }

 

    #endregion

 

    // IList

    #region 읽기 전용 여부 - IsReadOnly

 

    /// <summary>

    /// 읽기 전용 여부

    /// </summary>

    public virtual bool IsReadOnly

    {

        get

        {

            return false;

        }

    }

 

    #endregion

 

    // IList

    #region 고정 크기 여부 - IsFixedSize

 

    /// <summary>

    /// 고정 크기 여부

    /// </summary>

    public virtual bool IsFixedSize

    {

        get

        {

            return true;

        }

    }

 

    #endregion

 

    // IList

    #region 인덱서 - this[index]

 

    /// <summary>

    /// 인덱서

    /// </summary>

    /// <param name="index">인덱스</param>

    /// <returns></returns>

    public object this[int index]

    {

        get

        {

            return this.sourceCollection[index];

        }  

        set

        {

        }

    }

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 생성자 - ObservableCollectionVirtualSource(sourceCollection)

 

    /// <summary>

    /// 생성자

    /// </summary>

    /// <param name="sourceCollection">소스 컬렉션</param>

    public ObservableCollectionVirtualSource(ObservableCollection<object> sourceCollection)

    {

        this.sourceCollection = sourceCollection;

 

        SetPropertyDescriptorCollection();

 

        this.rowCount    = GetRowCount();

        this.columnCount = GetColumnCount();

    }

 

    #endregion

 

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

    ////////////////////////////////////////////////////////////////////////////////////////// Internal

 

    #region 행 값 설정하기 - SetRowValue(row, columnIndex, value)

 

    /// <summary>

    /// 행 값 설정하기

    /// </summary>

    /// <param name="row">행 객체</param>

    /// <param name="columnIndex">컬럼 인덱스</param>

    /// <param name="value"></param>

    internal void SetRowValue(object row, int columnIndex, object value)

    {

        this.propertyDescriptorCollection[columnIndex].SetValue(row, value);

    }

 

    #endregion

 

    #region 행 값 구하기 - GetRowValue(row, columnIndex)

 

    /// <summary>

    /// 행 값 구하기

    /// </summary>

    /// <param name="row">행 객체</param>

    /// <param name="columnIndex">컬럼 인덱스</param>

    /// <returns>행 값</returns>

    internal object GetRowValue(object row, int columnIndex)

    {

        return this.propertyDescriptorCollection[columnIndex].GetValue(row);

    }

 

    #endregion

 

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    // IList

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

        

    /// <summary>

    /// 열거자 구하기

    /// </summary>

    /// <returns>열거자</returns>

    public virtual IEnumerator GetEnumerator()

    {

        return null;

    }

 

    #endregion

 

    // IList

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

 

    /// <summary>

    /// 복사하기

    /// </summary>

    /// <param name="array">배열</param>

    /// <param name="index">인덱스</param>

    public virtual void CopyTo(Array array, int index)

    {

    }

 

    #endregion

 

    // IList

    #region 추가하기 - Add(value)

 

    /// <summary>

    /// 추가하기

    /// </summary>

    /// <param name="value"></param>

    /// <returns>처리 결과</returns>

    public virtual int Add(object value)

    {

        throw new NotImplementedException();

    }

 

    #endregion

 

    // IList

    #region 지우기 - Clear()

 

    /// <summary>

    /// 지우기

    /// </summary>

    public virtual void Clear()

    {

        throw new NotImplementedException();

    }

 

    #endregion

 

    // IList

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

 

    /// <summary>

    /// 포함 여부 구하기

    /// </summary>

    /// <param name="value"></param>

    /// <returns>포함 여부</returns>

    public virtual bool Contains(object value)

    {

        throw new NotImplementedException();

    }

 

    #endregion

 

    // IList

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

 

    /// <summary>

    /// 인덱스 구하기

    /// </summary>

    /// <param name="value"></param>

    /// <returns>인덱스</returns>

    public virtual int IndexOf(object value)

    {

        throw new NotImplementedException();

    }

 

    #endregion

 

    // IList

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

 

    /// <summary>

    /// 삽입하기

    /// </summary>

    /// <param name="index">인덱스</param>

    /// <param name="value"></param>

    public virtual void Insert(int index, object value)

    {

        throw new NotImplementedException();

    }

 

    #endregion

 

    // IList

    #region 제거하기 - Remove(value)

 

    /// <summary>

    /// 제거하기

    /// </summary>

    /// <param name="value"></param>

    public virtual void Remove(object value)

    {

        throw new NotImplementedException();

    }

 

    #endregion

 

    // IList

    #region 제거하기 - RemoveAt(index)

 

    /// <summary>

    /// 제거하기

    /// </summary>

    /// <param name="index">인덱스</param>

    public virtual void RemoveAt(int index)

    {

        throw new NotImplementedException();

    }

 

    #endregion

 

    // ITypedList

    #region 항목 속성 컬렉션 구하기 - GetItemProperties(propertyDescriptorArray)

 

    /// <summary>

    /// 항목 속성 컬렉션 구하기

    /// </summary>

    /// <param name="propertyDescriptorArray">속성 설명자 배열</param>

    /// <returns>항목 속성 컬렉션</returns>

    public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] propertyDescriptorArray)

    {

        return this.propertyDescriptorCollection;

    }

 

    #endregion

 

    // ITypedList

    #region 리스트명 구하기 - GetListName(propertyDescriptorArray)

 

    /// <summary>

    /// 리스트명 구하기

    /// </summary>

    /// <param name="propertyDescriptorArray">속성 설명자 배열</param>

    /// <returns>리스트명</returns>

    public string GetListName(PropertyDescriptor[] propertyDescriptorArray)

    {

        if(this.sourceCollection == null)

        {

            return "Entity";

        }

        else

        {

            if(this.sourceCollection.Count == 0)

            {

                return "Entity";

            }

            else

            {

                string typeString = this.sourceCollection[0].GetType().ToString();

 

                int index = typeString.LastIndexOf('.');

 

                if(index > -1)

                {

                    return typeString.Substring(index + 1);

                }

                else

                {

                    return typeString;

                }

            }

        }

    }

 

    #endregion

 

    ////////////////////////////////////////////////////////////////////////////////////////// Protected

 

    #region 속성 설명자 컬렉션 설정하기 - SetPropertyDescriptorCollection()

 

    /// <summary>

    /// 속성 설명자 컬렉션 설정하기

    /// </summary>

    protected virtual void SetPropertyDescriptorCollection()

    {

        if(this.sourceCollection == null || this.sourceCollection.Count == 0)

        {

            this.propertyDescriptorCollection = null;

        }

        else

        {

            this.propertyDescriptorCollection = TypeDescriptor.GetProperties(this.sourceCollection[0]);

        }

    }

 

    #endregion

 

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

 

    #region 로우 카운트 구하기 - GetRowCount()

 

    /// <summary>

    /// 로우 카운트 구하기

    /// </summary>

    /// <returns>로우 카운트</returns>

    private int GetRowCount()

    {

        if(this.sourceCollection == null)

        {

            return 0;

        }

 

        return this.sourceCollection.Count;

    }

 

    #endregion

 

    #region 컬럼 카운트 구하기 - GetColumnCount()

 

    /// <summary>

    /// 컬럼 카운트 구하기

    /// </summary>

    /// <returns>컬럼 카운트</returns>

    private int GetColumnCount()

    {

        if(this.sourceCollection == null || this.sourceCollection.Count == 0)

        {

            return 0;

        }

 

        return this.propertyDescriptorCollection.Count;

    }

 

    #endregion

}

 

 

ObservableCollectionVirtualSourcePropertyDescriptor.cs

 

 

using System;

using System.ComponentModel;

 

/// <summary>

/// 관찰 가능 컬렉션 가상 소스 속성 설명자

/// </summary>

public class ObservableCollectionVirtualSourcePropertyDescriptor : PropertyDescriptor

{

    //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

    #region Field

 

    /// <summary>

    /// 속성명

    /// </summary>

    private string propertyName;

 

    /// <summary>

    /// 속성 타입

    /// </summary>

    private Type propertyType;

 

    /// <summary>

    /// 읽기 전용 여부

    /// </summary>

    private bool isReadOnly;

 

    /// <summary>

    /// 가상 소스

    /// </summary>

    private ObservableCollectionVirtualSource virtualSource;

 

    /// <summary>

    /// 인덱스

    /// </summary>

    private int index;

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Property

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 컴포넌트 타입 - ComponentType

 

    /// <summary>

    /// 컴포넌트 타입

    /// </summary>

    public override Type ComponentType

    {

        get

        {

            return typeof(ObservableCollectionVirtualSource);

        }

    }

 

    #endregion

 

    #region 명칭 - Name

 

    /// <summary>

    /// 명칭

    /// </summary>

    public override string Name

    {

        get

        {

            return this.propertyName;

        }

    }

 

    #endregion

 

    #region 속성 타입 - PropertyType

 

    /// <summary>

    /// 속성 타입

    /// </summary>

    public override Type PropertyType

    {

        get

        {

            return this.propertyType;

        }

    }

 

    #endregion

 

    #region 읽기 전용 여부 - IsReadOnly

 

    /// <summary>

    /// 읽기 전용 여부

    /// </summary>

    public override bool IsReadOnly

    {

        get

        {

            return this.isReadOnly;

        }

    }

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 생성자 - ObservableCollectionVirtualSourcePropertyDescriptor(virtuslSource, index, propertyName, propertyType, isReadOnly)

 

    /// <summary>

    /// 생성자

    /// </summary>

    /// <param name="virtuslSource">가상 소스</param>

    /// <param name="index">인덱스</param>

    /// <param name="propertyName">속성명</param>

    /// <param name="propertyType">속성 타입</param>

    /// <param name="isReadOnly">읽기 전용 여부</param>

    public ObservableCollectionVirtualSourcePropertyDescriptor(ObservableCollectionVirtualSource virtuslSource, int index,

        string propertyName, Type propertyType, bool isReadOnly) : base(propertyName, null)

    {

        this.virtualSource = virtuslSource;

        this.index         = index;

        this.propertyName  = propertyName;

        this.propertyType  = propertyType;

        this.isReadOnly    = isReadOnly;

    }

 

    #endregion

 

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

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 값 리셋 가능 여부 구하기 - CanResetValue(component)

 

    /// <summary>

    /// 값 리셋 가능 여부 구하기

    /// </summary>

    /// <param name="component">컴포넌트</param>

    /// <returns>값 리셋 가능 여부</returns>

    public override bool CanResetValue(object component)

    {

        return false;

    }

 

    #endregion

 

    #region 값 리셋하기 - ResetValue(component)

 

    /// <summary>

    /// 값 리셋하기

    /// </summary>

    /// <param name="component">컴포넌트</param>

    public override void ResetValue(object component)

    {

    }

 

    #endregion

 

    #region 값 설정하기 - SetValue(component, value)

 

    /// <summary>

    /// 값 설정하기

    /// </summary>

    /// <param name="component">컴포넌트</param>

    /// <param name="value"></param>

    public override void SetValue(object component, object value)

    {

        this.virtualSource.SetRowValue(component, this.index, value);

    }

 

    #endregion

 

    #region 값 구하기 - GetValue(component)

 

    /// <summary>

    /// 값 구하기

    /// </summary>

    /// <param name="component">컴포넌트</param>

    /// <returns></returns>

    public override object GetValue(object component)

    {

        return this.virtualSource.GetRowValue(component, this.index);

    }

 

    #endregion

 

    #region 값 직렬화 필수 여부 구하기 - ShouldSerializeValue(component)

 

    /// <summary>

    /// 값 직렬화 필수 여부 구하기

    /// </summary>

    /// <param name="component">컴포넌트</param>

    /// <returns>값 직렬화 필수 여부</returns>

    public override bool ShouldSerializeValue(object component)

    {

        return true;

    }

 

    #endregion

}

 

----------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요