반응형

C# Winform에서 Datagridview에 Datasource를 정렬이 가능한 리스트로 설정하는 방법

 

정렬이 가능하도록 하는 SortableBindingList class 추가

	public class SortableBindingList<T> : BindingList<T>
	{
		private readonly Dictionary<Type, PropertyComparer<T>> comparers;
		private bool isSorted;
		private ListSortDirection listSortDirection;
		private PropertyDescriptor propertyDescriptor;

		public SortableBindingList()
			: base(new List<T>())
		{
			this.comparers = new Dictionary<Type, PropertyComparer<T>>();
		}

		public SortableBindingList(IEnumerable<T> enumeration)
			: base(new List<T>(enumeration))
		{
			this.comparers = new Dictionary<Type, PropertyComparer<T>>();
		}

		protected override bool SupportsSortingCore
		{
			get { return true; }
		}

		protected override bool IsSortedCore
		{
			get { return this.isSorted; }
		}

		protected override PropertyDescriptor SortPropertyCore
		{
			get { return this.propertyDescriptor; }
		}

		protected override ListSortDirection SortDirectionCore
		{
			get { return this.listSortDirection; }
		}

		protected override bool SupportsSearchingCore
		{
			get { return true; }
		}
		
		public void Sort(Comparison<T> comparison)
		{
			List<T> itemsList = (List<T>)this.Items;
			itemsList.Sort(comparison);
			this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
		}

		protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
		{
			List<T> itemsList = (List<T>)this.Items;

			Type propertyType = property.PropertyType;
			PropertyComparer<T> comparer;
			if (!this.comparers.TryGetValue(propertyType, out comparer))
			{
				comparer = new PropertyComparer<T>(property, direction);
				this.comparers.Add(propertyType, comparer);
			}

			comparer.SetPropertyAndDirection(property, direction);
			itemsList.Sort(comparer);

			this.propertyDescriptor = property;
			this.listSortDirection = direction;
			this.isSorted = true;

			this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
		}

		protected override void RemoveSortCore()
		{
			this.isSorted = false;
			this.propertyDescriptor = base.SortPropertyCore;
			this.listSortDirection = base.SortDirectionCore;

			this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
		}

		protected override int FindCore(PropertyDescriptor property, object key)
		{
			int count = this.Count;
			for (int i = 0; i < count; ++i)
			{
				T element = this[i];
				if (property.GetValue(element).Equals(key))
				{
					return i;
				}
			}

			return -1;
		}
	}
	public class PropertyComparer<T> : IComparer<T>
	{
		private readonly IComparer comparer;
		private PropertyDescriptor propertyDescriptor;
		private int reverse;

		public PropertyComparer(PropertyDescriptor property, ListSortDirection direction)
		{
			this.propertyDescriptor = property;
			Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType);
			this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null);
			this.SetListSortDirection(direction);
		}

		#region IComparer<T> Members

		public int Compare(T x, T y)
		{
			return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y));
		}

		#endregion

		private void SetPropertyDescriptor(PropertyDescriptor descriptor)
		{
			this.propertyDescriptor = descriptor;
		}

		private void SetListSortDirection(ListSortDirection direction)
		{
			this.reverse = direction == ListSortDirection.Ascending ? 1 : -1;
		}

		public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction)
		{
			this.SetPropertyDescriptor(descriptor);
			this.SetListSortDirection(direction);
		}
	}

 

Datagridview의 DataSource에 SortableBindingList 인스턴스 지정

	public partial class GUIControlsExample : Form
	{
		private SortableBindingList<Student> studentsViewModel;

		public GUIControlsExample()
		{
			InitializeComponent();

			this.StartPosition = FormStartPosition.CenterParent;
		}

		private void GUIControlsExample_Load(object sender, EventArgs e)
		{
			studentsViewModel = new SortableBindingList<Student>();
			dgvStudentList.DataSource = studentsViewModel;

			School school = new School()
			{
				Name = "Korea Hightschool",
				Address = "Seoul"
			};

			Class classInfo = new Class(school)
			{
				ClassNumber = 5,
				Location = "Second floor",
			};

			for (int i = 0; i < 20; i++)
			{
				studentsViewModel.Add(new Student(classInfo)
				{
					NumberInClass = i + 1,
					Name = $"{i + 1}_Ben",
					BirthDate = DateTime.Now,
				});
			}
		}
	}

결과화면

반응형

'[====== Development ======] > C#' 카테고리의 다른 글

C# DatagridView 조건에 따라 Cell 속성 변경  (0) 2021.02.09
C# Winform Datagridview Style 적용  (0) 2021.02.09
Email 전송 기능  (0) 2021.02.05
DateTime Extention Method  (0) 2021.02.05
파일 검색  (0) 2021.02.05

+ Recent posts