|
using System; |
|
using System.Collections.Generic; |
|
using System.ComponentModel; |
|
using System.Data; |
|
using System.Diagnostics; |
|
using System.Drawing; |
|
using System.Linq; |
|
using System.Runtime.CompilerServices; |
|
using System.Text; |
|
using System.Threading.Tasks; |
|
using System.Windows.Forms; |
|
|
|
namespace INotifyPropertyChanged_SortableBindingList_test |
|
{ |
|
public partial class Form1 : Form |
|
{ |
|
List<Student> studentList = new List<Student>(); |
|
private BindingSource studentBindingSource = new BindingSource(); |
|
|
|
private SortableBindingList<Student> studentBindingList; |
|
|
|
public Form1() |
|
{ |
|
InitializeComponent(); |
|
|
|
studentList.Add(new Student("Tom", 17, 33.2, false)); |
|
studentList.Add(new Student("Sara", 19, 53.4, true)); |
|
studentList.Add(new Student("홍길동", 15, 130.2, false)); |
|
studentList.Add(new Student("이순신", 16, 43.2, true)); |
|
studentList.Add(new Student("Ace", 15, 23.2, false)); |
|
|
|
studentBindingList = new SortableBindingList<Student>(studentList); |
|
|
|
studentBindingSource.DataSource = studentBindingList; |
|
this.dataGridView1.DataSource = studentBindingSource; |
|
} |
|
|
|
private void Form1_Load(object sender, EventArgs e) |
|
{ |
|
|
|
} |
|
|
|
// 추가 버튼 click |
|
private void button1_Click(object sender, EventArgs e) |
|
{ |
|
studentBindingList.Add(new Student("유관순", 17, 45, false)); |
|
} |
|
|
|
// 삭제 버튼 click |
|
private void button2_Click(object sender, EventArgs e) |
|
{ |
|
int rowIndex = this.dataGridView1.CurrentCell.RowIndex; |
|
int columnIndex = this.dataGridView1.CurrentCell.ColumnIndex; |
|
Debug.WriteLine($" 삭제될 cell ; row = {rowIndex}, column = {columnIndex}"); |
|
|
|
DataGridViewRow row = this.dataGridView1.Rows[rowIndex]; |
|
Student currentStudent = row.DataBoundItem as Student; |
|
Debug.WriteLine($"-- 삭제될 student = Name={currentStudent.Name}, Weight={currentStudent.Weight}, 안경={currentStudent.Glass}"); |
|
|
|
this.dataGridView1.Rows.RemoveAt(rowIndex); |
|
} |
|
|
|
// Info 버튼 click |
|
private void button3_Click(object sender, EventArgs e) |
|
{ |
|
int rowIndex = this.dataGridView1.CurrentCell.RowIndex; |
|
int columnIndex = this.dataGridView1.CurrentCell.ColumnIndex; |
|
|
|
Debug.WriteLine($"current cell ; row = {rowIndex}, column = {columnIndex}"); |
|
|
|
//DataGridViewRow row = this.dataGridView1.SelectedRows[0]; |
|
DataGridViewRow row = this.dataGridView1.Rows[rowIndex]; |
|
|
|
Student currentStudent = row.DataBoundItem as Student; |
|
if(currentStudent != null) |
|
{ |
|
Debug.WriteLine($"총 student 수 = {this.studentBindingList.Count}"); |
|
for(int i=0; i<this.studentBindingList.Count; i++) |
|
{ |
|
Debug.WriteLine($" student {i} = {this.studentBindingList[i].Name}, Weight={this.studentBindingList[i].Weight}"); |
|
} |
|
Debug.WriteLine($"-- current student => {currentStudent.Name}, {currentStudent.Age}, {currentStudent.Weight}, 안경={currentStudent.Glass}"); |
|
} |
|
} |
|
|
|
// 변경 버튼 click |
|
private void button4_Click(object sender, EventArgs e) |
|
{ |
|
if(this.studentBindingList.Count > 0) |
|
{ |
|
Student student = this.studentBindingList[0]; |
|
student.Weight += 1; |
|
} |
|
|
|
} |
|
} |
|
|
|
|
|
|
|
public class Student : INotifyPropertyChanged |
|
{ |
|
private double _weight; |
|
|
|
public string Name { get; set; } |
|
public int Age { get; set; } |
|
public double Weight |
|
{ |
|
get |
|
{ |
|
return _weight; |
|
} |
|
|
|
set |
|
{ |
|
if (value != this._weight) |
|
{ |
|
this._weight = value; |
|
NotifyPropertyChanged(); |
|
} |
|
} |
|
} |
|
public bool Glass { get; set; } = false; // 안경끼면, true |
|
|
|
public event PropertyChangedEventHandler PropertyChanged; |
|
|
|
public Student(string name, int age, double weight, bool glass) |
|
{ |
|
this.Name = name; |
|
this.Age = age; |
|
this.Weight = weight; |
|
this.Glass = glass; |
|
} |
|
|
|
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") |
|
{ |
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); |
|
} |
|
|
|
|
|
|
|
} |
|
|
|
public class SortableBindingList<T> : BindingList<T> where T : class |
|
{ |
|
private bool _isSorted; |
|
private ListSortDirection _sortDirection = ListSortDirection.Ascending; |
|
private PropertyDescriptor _sortProperty; |
|
|
|
public SortableBindingList() |
|
{ |
|
} |
|
|
|
public SortableBindingList(IList<T> list) |
|
: base(list) |
|
{ |
|
} |
|
|
|
// Gets a value indicating whether the list supports sorting. |
|
protected override bool SupportsSortingCore |
|
{ |
|
get { return true; } |
|
} |
|
|
|
// Gets a value indicating whether the list is sorted. |
|
protected override bool IsSortedCore |
|
{ |
|
get { return _isSorted; } |
|
} |
|
|
|
// Gets the direction the list is sorted. |
|
protected override ListSortDirection SortDirectionCore |
|
{ |
|
get { return _sortDirection; } |
|
} |
|
|
|
// Gets the property descriptor that is used for sorting the list if sorting is implemented in a derived class; otherwise, returns null |
|
protected override PropertyDescriptor SortPropertyCore |
|
{ |
|
get { return _sortProperty; } |
|
} |
|
|
|
// Removes any sort applied with ApplySortCore if sorting is implemented |
|
protected override void RemoveSortCore() |
|
{ |
|
_sortDirection = ListSortDirection.Ascending; |
|
_sortProperty = null; |
|
_isSorted = false; //thanks Luca |
|
} |
|
|
|
// Sorts the items if overridden in a derived class |
|
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) |
|
{ |
|
_sortProperty = prop; |
|
_sortDirection = direction; |
|
|
|
List<T> list = Items as List<T>; |
|
if (list == null) return; |
|
|
|
list.Sort(Compare); |
|
|
|
_isSorted = true; |
|
//fire an event that the list has been changed. |
|
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); |
|
} |
|
|
|
private int Compare(T lhs, T rhs) |
|
{ |
|
var result = OnComparison(lhs, rhs); |
|
//invert if descending |
|
if (_sortDirection == ListSortDirection.Descending) |
|
result = -result; |
|
return result; |
|
} |
|
|
|
private int OnComparison(T lhs, T rhs) |
|
{ |
|
object lhsValue = lhs == null ? null : _sortProperty.GetValue(lhs); |
|
object rhsValue = rhs == null ? null : _sortProperty.GetValue(rhs); |
|
if (lhsValue == null) |
|
{ |
|
return (rhsValue == null) ? 0 : -1; //nulls are equal |
|
} |
|
if (rhsValue == null) |
|
{ |
|
return 1; //first has value, second doesn't |
|
} |
|
if (lhsValue is IComparable) |
|
{ |
|
return ((IComparable)lhsValue).CompareTo(rhsValue); |
|
} |
|
if (lhsValue.Equals(rhsValue)) |
|
{ |
|
return 0; //both are the same |
|
} |
|
//not comparable, compare ToString |
|
return lhsValue.ToString().CompareTo(rhsValue.ToString()); |
|
} |
|
} |
|
|
|
} |