■ ITypedList 인터페이스 : TypedCollection<T> 만들기 예제

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

using System;

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : Form

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Class

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

 

        #region 임직원 - Employee

 

        /// <summary>

        /// 임직원

        /// </summary>

        private class Employee

        {

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

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

 

            #region Field

 

            /// <summary>

            /// 아이디

            /// </summary>

            public string ID;

 

            /// <summary>

            /// 성명

            /// </summary>

            public string Name;

 

            #endregion

        }

 

        #endregion

 

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

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

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()

        {

            InitializeComponent();

 

            this.gridControl.DataSource = GetCollection(); // Employee 필드도 바인딩이 정상적으로 된다.

        }

 

        #endregion

 

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

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

 

        #region 컬렉션 구하기 - GetCollection()

 

        /// <summary>

        /// 컬렉션 구하기

        /// </summary>

        /// <returns>컬렉션</returns>

        private TypedCollection<Employee> GetCollection()

        {

            TypedCollection<Employee> collection = new TypedCollection<Employee>();

 

            collection.Add(new Employee(){ ID = "A", Name = "홍길동" });

            collection.Add(new Employee(){ ID = "B", Name = "강동구" });

            collection.Add(new Employee(){ ID = "C", Name = "홍길숙" });

 

            return collection;

        }

 

        #endregion

    }

}

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

※ this.gridControl은 그리드 컨트롤을 가정한다.

 

■ ITypedList 인터페이스 : TypedCollection<T> 만들기

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

TypedPropertyDescriptor.cs

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

 

namespace TestProject

{

    /// <summary>

    /// 타입 속성 설명자

    /// </summary>

    /// <typeparam name="T">타입</typeparam>

    public class TypedPropertyDescriptor<T> : PropertyDescriptor

    {

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

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

 

        #region Field

 

        /// <summary>

        /// GetValue 함수

        /// </summary>

        private Func<object, object> getValue;

 

        /// <summary>

        /// SetValue 액션

        /// </summary>

        private Action<object, object> setValue;

 

        /// <summary>

        /// 타입

        /// </summary>

        private Type type;

 

        #endregion

 

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

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

 

        #region 컴포넌트 타입 - ComponentType

 

        /// <summary>

        /// 컴포넌트 타입

        /// </summary>

        public override Type ComponentType

        {

            get

            {

                return typeof(TypedCollection<T>);

            }

        }

 

        #endregion

 

        #region 읽기 전용 여부 - IsReadOnly

 

        /// <summary>

        /// 읽기 전용 여부

        /// </summary>

        public override bool IsReadOnly

        {

            get

            {

                return false;

            }

        }

 

        #endregion

 

        #region 속성 타입 - PropertyType

 

        /// <summary>

        /// 속성 타입

        /// </summary>

        public override Type PropertyType

        {

            get

            {

                return this.type;

            }

        }

 

        #endregion

 

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

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

 

        #region 생성자 - TypedPropertyDescriptor(getValue, setValue, memberName, type)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="getValue">GetValue 함수</param>

        /// <param name="setValue">SetValue 액션</param>

        /// <param name="memberName">멤버명</param>

        /// <param name="type">타입</param>

        public TypedPropertyDescriptor(Func<object, object> getValue, Action<object, object> setValue, string memberName,

            Type type) : base(memberName, null)

        {

            this.getValue = getValue;

            this.setValue = setValue;

            this.type     = type;

        }

 

        #endregion

 

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

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

 

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

 

        /// <summary>

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

        /// </summary>

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

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

        public override bool CanResetValue(object component)

        {

            return false;

        }

 

        #endregion

 

        #region 값 구하기 - GetValue(component)

 

        /// <summary>

        /// 값 구하기

        /// </summary>

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

        /// <returns></returns>

        public override object GetValue(object component)

        {

            return this.getValue(component);

        }

 

        #endregion

 

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

 

        /// <summary>

        /// 값 리셋하기

        /// </summary>

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

        public override void ResetValue(object component)

        {

            this.setValue(component, null);

        }

 

        #endregion

 

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

 

        /// <summary>

        /// 값 설정하기

        /// </summary>

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

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

        public override void SetValue(object component, object value)

        {

            this.setValue(component, value);

        }

 

        #endregion

 

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

 

        /// <summary>

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

        /// </summary>

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

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

        public override bool ShouldSerializeValue(object component)

        {

            return true;

        }

 

        #endregion

    }

}

 

 

TypedCollection.cs

 

 

using System;

using System.Collections.ObjectModel;

using System.ComponentModel;

using System.Reflection;

 

namespace TestProject

{

    /// <summary>

    /// 타입 컬렉션

    /// </summary>

    /// <typeparam name="T">타입</typeparam>

    [Serializable]

    public class TypedCollection<T> : ObservableCollection<T>, ITypedList

    {

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

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

 

        #region Field

 

        /// <summary>

        /// 속성 설명자 컬렉션

        /// </summary>

        private PropertyDescriptorCollection propertyDescriptorCollection = new PropertyDescriptorCollection(null);

 

        #endregion

    

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

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

 

        #region 속성 설명자 컬렉션 - Properties

 

        /// <summary>

        /// 속성 설명자 컬렉션

        /// </summary>

        public PropertyDescriptorCollection Properties

        {

            get

            {

                return this.propertyDescriptorCollection;

            }

        }

 

        #endregion

    

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

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

 

        #region 아이템 속성들 구하기 - GetItemProperties(propertyDescriptorArray)

 

        /// <summary>

        /// 아이템 속성들 구하기

        /// </summary>

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

        /// <returns>속성 설명자 컬렉션</returns>

        public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] propertyDescriptorArray)

        {

            if(propertyDescriptorArray != null && propertyDescriptorArray.Length > 0)

            {

                return System.Windows.Forms.ListBindingHelper.GetListItemProperties(propertyDescriptorArray[0].PropertyType);

            }

            else

            {

                return this.propertyDescriptorCollection;

            }

        }

 

        #endregion

    

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

 

        /// <summary>

        /// 리스트명 구하기

        /// </summary>

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

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

        public string GetListName(PropertyDescriptor[] propertyDescriptorArray)

        {

            return this.ToString();

        }

 

        #endregion

 

        #region 추가하기 - Add(item)

 

        /// <summary>

        /// 추가하기

        /// </summary>

        /// <param name="item">아이템</param>

        public new void Add(T item)

        {

            if(base.Count == 0)

            {

                Type type = item.GetType();

 

                if(this.propertyDescriptorCollection.Count == 0)

                {

                    foreach(MemberInfo memberInfo in type.GetMembers())

                    {

                        switch(memberInfo.MemberType)

                        {

                            case MemberTypes.Field :

 

                                FieldInfo fieldInfo = memberInfo as FieldInfo;

 

                                this.propertyDescriptorCollection.Add

                                (

                                    new TypedPropertyDescriptor<T>

                                    (

                                        fieldInfo.GetValue,

                                       fieldInfo.SetValue,

                                        fieldInfo.Name,

                                        fieldInfo.FieldType

                                    )

                                );

                                

                                break;

 

                            case MemberTypes.Property :

 

                                PropertyInfo propertyInfo = memberInfo as PropertyInfo;

 

                                this.propertyDescriptorCollection.Add

                                (

                                    new TypedPropertyDescriptor<T>

                                    (

                                        propertyInfo.GetValue,

                                        propertyInfo.SetValue,

                                        propertyInfo.Name,

                                        propertyInfo.PropertyType

                                    )

                                );

 

                                break;

                        }

                    }

                }

                else

                {

                    foreach(PropertyDescriptor propertyDescriptor in this.propertyDescriptorCollection)

                    {

                        MemberInfo[] memberInfo = type.GetMember(propertyDescriptor.Name);

 

                        if(memberInfo == null || memberInfo.Length == 0)

                        {

                            throw new Exception(propertyDescriptor.Name + "가 존재하지 않습니다.");

                        }

                    }

                }

            }

 

            base.Add(item);

        }

 

        #endregion

 

        #region GetValue 함수 구하기 - GetGetValueFunc(memberName)

 

        /// <summary>

        /// GetValue 함수 구하기

        /// </summary>

        /// <param name="memberName">멤버명</param>

        /// <returns>GetValue 함수</returns>

        public Func<object, object> GetGetValueFunc(string memberName)

        {

            if(base.Count == 0)

            {

                return null;

            }

 

            Type type = base[0].GetType();

 

            FieldInfo fieldInfo = type.GetField(memberName);

 

            if(fieldInfo != null)

            {

                return fieldInfo.GetValue;

            }

            else

            {

                PropertyInfo propertyInfo = type.GetProperty(memberName);

 

                if(propertyInfo != null)

                {

                    return propertyInfo.GetValue;

                }

 

                return null;

            }

        }

 

        #endregion

    }

}

 

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

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요