Data Collection에서 사용 가능한 컬렉션의 종류를 설명합니다.
여기서는 필드와 속성을 모두 합쳐서 멤버(Member)라 정의합니다. 함수를 메서드라 부르고 List, Dictionary와 같은 데이터 형식을 컬렉션으로 부르기도 합니다.
최상위 계층인 TypeMapper 클래스를 상속받아 NotifyList<T> 컬렉션을 구현하였고 이 컬렉션을 기반으로 DataList<T> 와 VirtualList<T> 컬렉션을 구현하였습니다. 이러한 관계의 Class Diagram은 다음과 같습니다.
[그림 1] DataList와 VirtualList의 Class Diagram
NotifyList는 컬렉션에서 항목이 추가되거나 제거가 되었을 때 혹은, 항목의 값이 변경되었을 때 알림을 받을 수 있는 컬렉션입니다.
기본적으로는 CollectionChanged 이벤트와 ValueChanged 이벤트가 발생합니다. 그리고, 값이 변경될 때 알림을 받을 수 있는 조건은 몇가지가 존재하며 그 조건이 만족되면 ValueChanged 이벤트가 발생합니다. 아래는 해당조건입니다.
NotifyList<dynamic>
NotifyList<dynamic> 컬렉션은 Member를 직접 추가하거나 삭제할 수 있습니다. Member에 해당하는 값을 수정하면 ValueChanged 이벤트가 발생합니다. GenerateCode() 메서드를 호출하면 NotifyList<dynamic> 컬렉션에서 생성된 Member 정보를 사용하여 아래와 유사한 클래스 구조의 코드를 생성합니다.
#region ClassName /// <summary> /// 클래스를 정의합니다. /// </summary> public class ClassName { /// <summary>RegionID 입니다.</summary> public long RegionID; /// <summary>RegionDescription 입니다.</summary> public string RegionDescription; } #endregion
NotifyList.Members[i].SetValue() 메서드
T 타입에 상관없이 SetValue() 메서드를 사용하면 ValueChanged 이벤트가 항상 발생합니다.
INotifyValueChanged 인터페이스 상속
클래스를 선언할 때 INotifyValueChanged 인터페이스를 상속받고 속성 값이 변경될 때 ValueChanged 이벤트를 호출해주는 패턴을 구현합니다. 아래는 구현 방법입니다.
/// <summary> /// INotifyValueChanged 인터페이스를 사용하는 예제입니다. /// </summary> public class TestClass : INotifyValueChanged { /// <summary> /// 멤버의 값이 변경될 때 발생합니다. /// </summary> public event EventHandler<ValueChangedEventArgs> ValueChanged; /// <summary> /// ID 값입니다. /// </summary> string id; /// <summary> /// ID 값을 가져오거나 설정합니다. /// </summary> public string Id { get => this.id; set { var oldValue = this.id; this.id = value; // 변경 후 이벤트를 호출합니다. this.ValueChanged?.Invoke(this, new ValueChangedEventArgs(this, nameof(Id), value, oldValue)); } } }
다음과 같이 LINQ 구문이 사용 가능합니다.
var enumerable = from item in notifyList where item.Category == "Category1" select item;
NotifyList<T> 컬렉션을 상속받아 구현되었고 UI 컨트롤에 바인딩이 가능하도록 설계되었습니다. NotifyList<T> 컬렉션에서 데이터를 필터링하는 기능과 정렬하는 기능이 포함되었습니다.
필터 기능을 위해 Filters 컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. Add() 메서드를 사용하여 필터를 여러 번 추가하면, 필터 적용이 여러 번 수행되어 성능이 저하될 수 있습니다. 이럴 경우, AddRange() 메서드를 사용하여 2개 이상의 필터 조건을 한 번에 적용하는 것을 고려해야 합니다.
dataList.Filters.Add("rowid", RelationalOperator.LessThanOrEqual, 1000);
정렬 기능을 위해 Sorts 컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. 필터와 동일하게 Add() 메서드를 사용하여 정렬을 여러 번 추가하면, 정렬 적용이 여러번 수행되어 성능이 저하될 수 있습니다. 이럴 경우, AddRange() 메서드를 사용하여 2개 이상의 정렬 조건을 한 번에 적용하는 것을 고려해야 합니다.
dataList.Sorts.Add("rowid", ListSortDirection.Descending);
데이터베이스의 테이블의 항목이 추가 또는 제거되거나 전체 목록이 새로 고쳐질 때 알림을 제공하는 동적 데이터 컬렉션을 나타냅니다. VirtualList<T>는 다음과 같은 특징을 가지고 있습니다.
선언 방법
기본적인 선언 방법은 다음과 같습니다.
var virtualList = new VirtualList<dynamic>("TableName", "SQLite");
필터 기능을 위해 Filters 컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. DataList<T> 컬렉션과 다르게 Add() 메서드를 사용하여 필터 조건을 여러 번 추가하여도 성능에 영향을 받지 않습니다. VirtualList<T> 컬렉션은 필터 적용 후 실제 사용 시점에 데이터를 쿼리하기 떄문입니다.
virtualList.Filters.Add("rowid", RelationalOperator.LessThanOrEqual, 1000); // 필터 적용 후 아래와 같이 실제 사용 시점에 쿼리 후 데이터를 가져옵니다. var item = virtualList[2];
정렬 기능을 위해 Sorts 컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. DataList<T> 컬렉션과 다르게 Add() 메서드를 사용하여 정렬 조건을 여러 번 추가하여도 성능에 영향을 받지 않습니다. VirtualList<T> 컬렉션은 정렬 적용 후 실제 사용 시점에 데이터를 쿼리하기 떄문입니다.
virtualList.Sorts.Add("rowid", ListSortDirection.Descending); // 정렬 적용 후 아래와 같이 실제 사용 시점에 쿼리 후 데이터를 가져옵니다. var item = virtualList[2];