List<MyObj> objList = new List<MyObj>();
objList.Add(obj1);
objList.Add(obj2);
BindingSource bindingList = new BindingList(objList, null);
dataGridView1.DataSource = bindingList;
Сортировка в DataGridView
Код:
При этом я заранее в гриде создаю колонки, в свойстве DataPropertyName указываю имена свойств моего объекта.
Свойство грида AllowUserToOrderColumns стоит значение true.
Задача: Уметь сортировать по колонкам.
Нажимаю на заголовок колонки. При этом никакой сортировки не происходит.
Вопрос первый: почему?
Пытаясь на него ответить самому, я наткнулся на свойства класса BindingSource: SupportsSorting. Оно принимает значение true, если забиндинный объект реализует интерфейс IBindingList и поддерживает сортировку:
Цитата:
true if the data source is an IBindingList and supports sorting; otherwise, false.
Вопрос второй. Может ли быть это причиной проблемы, и как тогда ее решить, если изначально я работаю с обычным списком?
Использование объекта класса DataTable в качестве DataSource
- Создание своего листа, который бы переопределял необходимые свойства и методы интерфейса IBindingList
Код:
DataGridView dataGridView1 = new DataGridView();
BindingSource bindingSource1 = new BindingSource();
BindingSource bindingSource1 = new BindingSource();
Код:
bindingSource1.DataSource = GetData("Select * From Products");
dataGridView1.DataSource = bindingSource1;
dataGridView1.DataSource = bindingSource1;
Код:
private static DataTable GetData(string sqlCommand)
{
string connectionString = "Integrated Security=SSPI;" +
"Persist Security Info=False;" +
"Initial Catalog=Northwind;Data Source=localhost";
SqlConnection northwindConnection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(sqlCommand, northwindConnection);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = command;
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
adapter.Fill(table);
return table;
}
{
string connectionString = "Integrated Security=SSPI;" +
"Persist Security Info=False;" +
"Initial Catalog=Northwind;Data Source=localhost";
SqlConnection northwindConnection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(sqlCommand, northwindConnection);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = command;
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
adapter.Fill(table);
return table;
}
По второму пункту - вот пример реализации IBindingList путем наследованя класса BindingList<T>:
Код:
public class CustomBindingList<T> : BindingList<T>
{
private bool _isSorted;
private ListSortDirection _sortDirection = ListSortDirection.Ascending;
private PropertyDescriptor _sortProperty;
public CustomBindingList(List<T> elements) : base(elements)
{
}
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override bool IsSortedCore
{
get { return _isSorted; }
}
protected override ListSortDirection SortDirectionCore
{
get { return _sortDirection; }
}
protected override PropertyDescriptor SortPropertyCore
{
get { return _sortProperty; }
}
protected override void RemoveSortCore()
{
_sortDirection = ListSortDirection.Ascending;
_sortProperty = null;
}
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
_sortProperty = prop;
_sortDirection = direction;
if (_sortProperty == null) return; //nothing to sort on
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)
{
object lhsValue = lhs == null ? null : _sortProperty.GetValue(lhs);
object rhsValue = rhs == null ? null : _sortProperty.GetValue(rhs);
int result = 0;
if (rhsValue == null && lhsValue == null)
{
result = 0;
}
else
{
if (lhsValue == null)
{
result = -1;
}
else if (rhsValue == null)
{
result = 1;
}
else
{
if (lhsValue is IComparable)
{
result = ((IComparable)lhsValue).CompareTo(rhsValue);
}
else if (!lhsValue.Equals(rhsValue)) //not comparable, compare ToString
{
result = lhsValue.ToString().CompareTo(rhsValue.ToString());
}
}
}
if (_sortDirection == ListSortDirection.Descending)
result = -result;
return result;
}
{
private bool _isSorted;
private ListSortDirection _sortDirection = ListSortDirection.Ascending;
private PropertyDescriptor _sortProperty;
public CustomBindingList(List<T> elements) : base(elements)
{
}
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override bool IsSortedCore
{
get { return _isSorted; }
}
protected override ListSortDirection SortDirectionCore
{
get { return _sortDirection; }
}
protected override PropertyDescriptor SortPropertyCore
{
get { return _sortProperty; }
}
protected override void RemoveSortCore()
{
_sortDirection = ListSortDirection.Ascending;
_sortProperty = null;
}
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
_sortProperty = prop;
_sortDirection = direction;
if (_sortProperty == null) return; //nothing to sort on
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)
{
object lhsValue = lhs == null ? null : _sortProperty.GetValue(lhs);
object rhsValue = rhs == null ? null : _sortProperty.GetValue(rhs);
int result = 0;
if (rhsValue == null && lhsValue == null)
{
result = 0;
}
else
{
if (lhsValue == null)
{
result = -1;
}
else if (rhsValue == null)
{
result = 1;
}
else
{
if (lhsValue is IComparable)
{
result = ((IComparable)lhsValue).CompareTo(rhsValue);
}
else if (!lhsValue.Equals(rhsValue)) //not comparable, compare ToString
{
result = lhsValue.ToString().CompareTo(rhsValue.ToString());
}
}
}
if (_sortDirection == ListSortDirection.Descending)
result = -result;
return result;
}
Использование:
Код:
CustomBindingList<MyObj> objList = new CustomBindingList<MyObj>();
objList.Add(obj1);
objList.Add(obj2);
dGVCard.DataSource = objList;
objList.Add(obj1);
objList.Add(obj2);
dGVCard.DataSource = objList;
все, сортировка работает, пробуй :)