■ ITypedList 인터페이스를 사용해 TypedCollection<T>를 만드는 방법을 보여준다.
▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
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은 그리드 컨트롤을 가정한다.
▶ TypedPropertyDescriptor.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
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 } } |