리스트뷰 요소를 잘 보면 상단에 버튼처럼 클릭이 활성화된 항목들이 존재한다. 간혹 뭔가를 만들다 보면, 이들 항목을 기준으로, 즉 해당 칼럼을 기준으로 아이템들을 정렬해야 하는 경우가 생긴다.
이때 해당 리스트뷰(ListView)의 속성의 이벤트 탭에서 ColumnClick이라는 이벤트를 처리할 메서드를 지정하고 그 메서드에서 클릭된 칼럼을 분류, 그에 따른 정렬을 구현해주면 된다.
아래 그림은 DirectoryCleaner라는 말 그대로 디렉토리를 정리해주는 윈폼 프로그램으로 필자가 개인적으로 만들고 있는 프로그램 중 하나다.
특정 디렉토리에 저장된 파일들, 하위 디렉토리의 파일들까지 모두 탐색한 결과를 리스트뷰에 담아서 보여주고 있다. 이름, 경로, 최종 수정일, 용량에 대한 정보를 리스트 뷰에 저장했는데, 각 항목을 기준으로 정렬하는 기능을 한 번 구현해보도록 하자.
최초 클릭 시점에는 오름차순 정렬을, 두번째 클릭 시점을 기준으로는 내림차순 정렬을 실시하고 클릭 될 때마다 오름차순과 내림차순을 번갈아 가며 정렬을 수행하는데, 각 항목을 오름차순, 내림차순으로 결정 짓는 방법은 크게 두 가지 방법을 사용했다.
1. 파일 이름, 경로, 최종 수정일은 문자열의 사전 순서를 따른다.
사전 순서인 경우를 오름차순, 사전의 반대 순서인 경우를 내림차순으로 정의.
2. 용량은 숫자의 대소 비교를 따른다.
용량은 위 두 가지와는 상황이 조금 다르다. 크기라는 게 존재하기 때문에 문자열 정보를 숫자로 바꾸고 그 후 대소비교를 실시해 우리가 흔히 아는 오름차순, 내림차순을 적용한다.
private void lvFileList_ColumnClick(object sender, ColumnClickEventArgs e) { this.lvFileList.ListViewItemSorter = new ListViewItemComparer(e.Column); if (sortStatus[e.Column] == 1) sortStatus[e.Column] = 2; else sortStatus[e.Column] = 1; } class ListViewItemComparer : IComparer { private int col; public ListViewItemComparer() { col = 0; } public ListViewItemComparer(int column) { col = column; } public int Compare(object x, object y) { if (col == 0 || col == 1 || col == 2) { if (sortStatus[col] == 1) return String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text); else return -String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text); } else { double dx, dy; dx = Double.Parse(((ListViewItem)x).SubItems[col].Text); dy = Double.Parse(((ListViewItem)y).SubItems[col].Text); if (sortStatus[col] == 1) { if (dx < dy) return -1; else if (dx == dy) return 0; else return 1; } else { if (dx < dy) return 1; else if (dx == dy) return 0; else return -1; } } } }
리스트뷰의 아이템을 정렬하는 것은 ListView.ListViewItemSorter이며 이를 통해서 리스트뷰를 제어한다. 정렬에 관련된 세부 내용은 ListViewItemComparer라는 클래스에서 이루어진다.
이 때 유의해야 할 부분은 반드시 인터페이스인 IComparer를 구현해야 한다. 여기서 다룰 정렬 방식은 기본적인 정렬로, 칼럼 값을 적절히 처리하는 생성자, 그리고 두 오브젝트(아이템)을 비교할 Compare 메서드만 구현하면 문제 없이 정렬을 수행할 수 있다.
필자는 여기서 오름차순, 내림차순 정렬을 선정하기 위한 변수와 조건문 하나를 더 넣었을 뿐, ColumnClick 이벤트를 통한 리스트뷰 아이템의 정렬에 대한 내용은 MSDN 문서(링크)와 다른 부분이 없다.
'정리가 필요한 카테고리(추후 정리) > C#,Unity' 카테고리의 다른 글
C#WPF] 텍스트박스에 숫자만 입력하게 만들기 (0) | 2018.04.02 |
---|---|
C#] C# 6.0 요약 (0) | 2018.03.08 |
Xamarin] Xamarin.Forms 공식 가이드 따라 시작하기 (0) | 2017.12.03 |
C#] 접근 수정자(Acces Modifier) (0) | 2017.07.22 |
C#] 리스트뷰 항목(아이템) 더블 클릭 시 항목 읽어오기 (0) | 2017.05.16 |