How to: Sort ListView Items

How to: Sort ListView Items
http://msdn.microsoft.com/en-us/library/ms229643(VS.80).aspx


class ListViewItemComparer : IComparer
{
    private int column;
    public ListViewItemComparer() : this(0) {}
    public ListViewItemComparer(int column)
    {
        this.column = column;
    }
    public int Compare(object x, object y) // string compare
    {
        return String.Compare(((ListViewItem)x).SubItems[column].Text,
                                        ((ListViewItem)y).SubItems[column].Text);
    }
}

/////
public partial class Form1 : Form
{
[…]
      private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
      {
            // Set the column number that is to be sorted; default to ascending.
            this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column);
            // Perform the sort with these new sort options.
            this.listView1.Sort();
        }
}

Generic List Class Sort Method

public void Sort(Comparison<T> comparison)
http://msdn.microsoft.com/en-us/library/w56d4y5z.aspx


List<Person> pList = new List<Person>();
pList.Sort(ComparePersonByID);  // pList를 ID로 정렬하기

[…]
public class Person : IComparable<Person>
{
    public static Comparison<Person> ComparePersonByID =
        delegate(Person p1, Person p2)
        {
             return p1.ID.CompareTo(p2.ID);
        };

    […]
}

IEquatable.Equals

http://msdn.microsoft.com/ko-kr/library/ms131190(VS.95).aspx

// Person 클래스
public class Person : IEquatable<Person>
{
   // …
    public Person(string name, int age)
     {
         _name = name;
         _age = age;
     }

     public override string ToString()
     {
         return string.Format(“이름 : {0}\t나이 : {1}”, _name, _age);
     }

    // needed for ==
    public static bool operator == (Person p, Person q)
    {
         return p.Equals(q);
    }

    public static bool operator != (Person p, Person q)
    {
        return !p.Equals(q);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        return Equals((Person)obj);
    }

    public bool Equals(Person other)
    {
        if (object.ReferenceEquals(this, other))
            return true;
        return (Name==other.Name) && (Age==other.Age);
    }
}


// aList에 포함된 세 사람 중에 둘리와 일치하는 사람이 있는지 확인한다
private static void Main(string[] args)
{
    List<Person> aList = new List<Person>();
    aList.Add(new Person(“둘리”, 1000));
    aList.Add(new Person(“희동이”, 3));
    aList.Add(new Person(“고길동”, 40));

    Person s = new Person(“둘리”, 1000);
    bool result = false;
    foreach (Person p in aList)
    {
         if (p == s)
         {
             result = true;
             break;
         }
     }

    // 또는 foreach를 사용하는 방법대신, List에 Find 또는 FindIndex를 사용한다.
    Person f = aList.Find(delegate(Person o)
    {
        return o == s; // 리스트에 o가 s와 일치하는 것이 있으면 그 Person 반환
    }
);

    int index = aList.FindIndex(delegate(Person o)
    {
        return o == s; // 리스트에 o가 s와 일치하는 것이 있으면 그 index 반환
    }
);

}

Assignment 4

연습문제 (4)


□ 단원 : C# WinForm
□ 목표 : Collections & FileIO & C# WinForm & Controls & GDI+ & Dialog
□ 주요 연습 내용 : Graphics, ListView
□ 준비자료 : QuakeData.cs 지진데이터


4100722456.txt사용자 삽입 이미지
[연습문제] Ex4 (Due by 12/06 화 24시까지)
-cyber 강의실 (cyber.dku.edu)로 source code, executable file, solution/project VC# file, 보고서를 학번_이름_Ex4.zip으로 묶어서 낼 것. 보고서 (30%)


[연습문제]


1. QuakeDataComparer.cs 파일에는 IComparer<QuakeData> 인터페이스를 상속받은 각종 비교 클래스들을 구현한다.  QuakeDataManager.cs에서 qList의 SortList에 사용됨. (10%)
– class QuakeMonthComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeDayComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeTimeComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeLatComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeLonComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeMagnitudeComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeDepthComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }


2. ListViewItemComparer.cs 파일에는 IComparer 인터페이스를 상속받은 ListViewIntegerItemComparer와 ListViewDoubleItemComparer 클래스를 구현한다. MainForm.cs에서 ListView의 SortListView에 사용됨. (10%)
(힌트: http://msdn.microsoft.com/en-us/library/ms996467.aspx)
– class ListViewIntegerItemComparer : IComparer
{ public int Compare(object x, object y) // 내부구현 필요 }
– class ListViewDoubleItemComparer : IComparer
{ public int Compare(object x, object y) // 내부구현 필요 }


3. QuakeDataManager.cs에 QuakeDataManager 클래스를 구현한다. (10%)
– private List<QuakeData> pList = null;
그리고 메소드는 다음을 포함한다.
// cvs(comma separated value) 파일을 읽어서, QuakeData를 pList에 추가
// StreamReader 사용
– public void LoadFile(string path, ref List<QuakeData> pList) { // 내부구현필요 }
// pList의 모든 QuakeData를 cvs(comma separated value) 텍스트 파일로 저장
// StreamWriter 사용
– public void WriteFile(string path) { // 내부구현 필요 }
// 리스트 데이터를  Year, Month, Day, Time, Lat, Lon, Magnitude, Depth 순서로 정렬
// QuakeMonthComparer, QuakeDataComparer, QuakeTimeComparer 등을 사용
– public void SortList(int index) { // 내부구현 필요 }


4. MainForm에 메뉴, 툴바, 탭컨트롤을 추가한다. (10%)사용자 삽입 이미지사용자 삽입 이미지


File 메뉴항목
 -New: 새로 그리기
 -Open/Save: 열기/저장하기
 -Print: 프린트로 출력하기 (optional)
 -Exit: 응용프로그램 종료
Data 메뉴항목
 -Find : 자료 찾기
View 메뉴항목
 -List: 리스트뷰로 보기
 -Map: 맵뷰로 보기


툴바에 메뉴 항목과 동일한 내용을 추가한다.
-New/Open/Save/Print/Close 메뉴항목 => New/Open/Save/Print/Close 툴바 버튼 추가
-Data 메뉴 항목=> Find Data 툴바 버튼 추가
-View 메뉴 항목 => ListView/MapView 툴바 콤보박스 추가


탭컨트롤에는 ListView와 PictureBox 컨트롤을 추가한다.
-첫 번째 TabPage에는 ListView를 추가하고, View는 Detail로 바꾼 후, Data를 보여줄 수 있도록 Column Header (Year/Month/Day/Time/Latitude/Longitude/Magnitude/Depth) 추가


-두 번째 TabPage에는 PictureBox를 추가하고, BackgroundImage로 Image에 Resources 디렉토리 안에 있는 “2_no_clouds_2K.jpg”를 추가


4. MainForm에 각종 이벤트 핸들러를 추가한다. (30%)
– private List<QuakeData> pList = new List<QuakeData>();
– private QuakeDataManager manager = new QuakeDataManager();
그리고 메소드는 다음을 포함한다.
// Exit – 메인폼을 닫고 응용프로그램 종료
– private void exitToolStripMenuItem_Click(object sender, EventArgs e) { … }
// Open – 파일을 읽어서 pList에 데이터를 로딩하고 listView와 pictureBox를 update
– private void openToolStripMenuItem_Click(object sender, EventArgs e) { … }
// Save – pList 데이터를 파일에 저장
– private void saveToolStripMenuItem_Click(object sender, EventArgs e) { …}
// 리스트컬럼클릭 – 클릭된 컬럼을 기준으로 정렬
// QuakeDataManager의 SortList와 listView의 SortListView를 사용
– private void listView1_ColumnClick(object sender, EventArgs e) { … }
// 리스트뷰의 정렬
// ListViewIntegerItemComparer와 ListViewDoubleItemComparer를 사용
– private void SortListView(int index) { … }


// listView와 pictureBox의 탭페이지 선택을 바꿔주는 메뉴항목과 탭컨트롤에서 페이지를 직접 선택할 시 메뉴항목에 Checked 업데이트
– private void listToolStripMenuItem_Click(object sender, EventArgs e) { …}
– private void mapToolStripMenuItem_Click(object sender, EventArgs e) { …}
– private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) { …}
// MainForm의 Resize할 때 listView와 pictureBox 무효화를 사용해 다시 그리기
– private void MainForm_Resize(object sender, EventArgs e) { …}


5. 비모달형 대화상자 (Modeless Dialog)인 SearchForm을 새로 추가하고 MainForm과 연동한다. (extra 10%)
– 전체 리스트에서 일정 영역만 Search해서 listView와 pictureBox에서 나타낼 수 있는
SearchForm 대화상자를 추가한다.


6. 본인이 원하는 기능을 더 추가하고, 결과를 모두 출력해서 넣는다. (보고서 점수에 포함)

결과예시: 사용자 삽입 이미지사용자 삽입 이미지

PersonListView

PersonListView
-Person 정보 FileIO (csv format) 파일 읽기, 저장하기
-리스트뷰에 파일읽어서 열기 및 저장하기
-여기에 리스트뷰의 칼럼을 클릭하면 그 순서대로 전체 항목을 정렬하기 추가해보기
-여기에 사람정보 (이름, ID, 전화번호, 주소) 입력을 위한 TextBox. 그리고 ID는 숫자만 입력가능한 모달형 대화상자 추가해보기
-여기에 사람을 찾는 모달리스형 대화상자 추가해보기