본문 바로가기
프로그래밍/C#

[C#] ListView 자료 정렬하기

by oedpus 2010. 12. 20.


지난 포스트에 이어 이번엔 ListView의 자료를 정렬하도록 하겠다.

일반적으로 응용프로그램을 사용하다보면 컬럼을 클릭하면 정렬하도록 나타내주는 기능인데
관련 자료는 MSDN에 친절하게 나와져 있다.

MSDN자료를 이용해서 이전에 올렸던 ListView 컨트롤을 정렬해 보도록 하겠다.

우선 cs 파일을 새로 생성해 준다.

우리가 추가해야될 클래스는 ColumnHeader를 상속받는 ColHeader와
정렬기능을 담당할 SortWrapper, SortComparer 클래스를 추가하게 될것이다.

ColumnHeader에 대한 내용은 아래 MSDN을 참조하기 바란다.
http://msdn.microsoft.com/ko-kr/library/system.windows.forms.columnheader(v=VS.80).aspx

요약하자면 Column명을 입력하고 속성들을 넣어주는 클래스이다.

먼저 ColHeader클래스를 정의하도록 하겠다.

    public class ColHeader : ColumnHeader
    {
        public bool ascending;

        // 생성자를 통해 컬럼명, 사이즈, 정렬위치, 정렬 여부를 설정하도록 생성자를 오버로딩 해준다.
        public ColHeader(string text, int width, HorizontalAlignment align, bool asc)
        {
            this.Text = text;
            this.Width = width;
            this.TextAlign = align;
            this.ascending = asc;
        }
    }

여기까지가 ColHeader클래스의 끝이다.
이제 SortWrapper클래스를 정의해 필드들을 정리하도록 하겠다.

    public class SortWrapper
    {
        internal ListViewItem sortItem;
        internal int sortColumn;


        // SortWrapper 클래스를 재정의 하는데 이때 클릭했을 때 컬럼 정보와 아이템들을 가져온다.
        public SortWrapper(ListViewItem Item, int iColumn)
        {
            sortItem = Item;
            sortColumn = iColumn;
        }

        // Text 라는 이름의 프로퍼티를 이용해 아이템들의 텍스트를 가져온다.
        public string Text
        {
            get
            {
                return sortItem.SubItems[sortColumn].Text;
            }
        }

        // ArrayList를 정렬하기 위한 클래스이다.
        public class SortComparer : IComparer
        {
            bool ascending;

            // 매개 변수로 정렬 방식을 넘긴다.
            // true 는 ascending, false는 descending.
            public SortComparer(bool asc)
            {
                this.ascending = asc;
            }

            // 두개의 오브젝트를 비교하는 메서드 이다.
            public int Compare(object x, object y)
            {
                SortWrapper xItem = (SortWrapper)x;
                SortWrapper yItem = (SortWrapper)y;

                string xText = xItem.sortItem.SubItems[xItem.sortColumn].Text;
                string yText = yItem.sortItem.SubItems[yItem.sortColumn].Text;
                return xText.CompareTo(yText) * (this.ascending ? 1 : -1);
            }
        }
    }

이제 본 프로젝트로 돌아와 ListView의 컬럼을 클릭했을 때 정렬할 수 있도록
다음과 같은 내용을 추가한다.

우선 이벤트를 정의 해야 한다. 이벤트를 살펴보면 ColumnClick이라는 이벤트가 있을 것이다.

        private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
        {

            // ColHeader 클래스의 객체를 생성한다.
            ColHeader clickedCol = (ColHeader)this.listView1.Columns[e.Column];

            // 오름차순 내림차순을 위해 정렬을 반대로 설정한다.
            clickedCol.ascending = !clickedCol.ascending;

            // ListView의 아이템들의 갯수를 뽑아온다.
            int numItems = this.listView1.Items.Count;

            // 데이터를 재설정 하는동안 보이지 않도록 설정한다.
            this.listView1.BeginUpdate();

            // ArrayList 컬렉션을 이용해서 SortWrapper 된 아이템들을 복사한다.
            ArrayList SortArray = new ArrayList();
            for (int i = 0; i < numItems; i++)
            {
                SortArray.Add(new SortWrapper(this.listView1.Items[i], e.Column));
            }

            // ArrayList 를 SortComparer 클래스를 이용해 값을 정렬한다.
            // 매개 변수로는 시작 인덱스 값과 종료 인덱스 값, IComparer를 이용해 값들을 비교한다.
            SortArray.Sort(0, SortArray.Count, new SortWrapper.SortComparer(clickedCol.ascending));

            // ListView를 초기화 하고 정렬이 된 값을 집어 넣는다.
            this.listView1.Items.Clear();
            for  (int i = 0; i < numItems; i++)
                this.listView1.Items.Add(((SortWrapper)SortArray[i]).sortItem);

            // ListView를 다시 보여지도록 만든다.
            this.listView1.EndUpdate();
        }

이제 프로그램을 실행해서 상단의 컬럼을 클릭하게 되면
그에 따라 오름차순 내림차순으로 정리되는 것을 확인할 수 있다.

'프로그래밍 > C#' 카테고리의 다른 글

[C#] ListView 컨트롤 사용하기  (0) 2010.12.17

댓글