ЗАКЛЮЧИТЕЛЬНОЕ Редактирование / Ответ: Я не могу придумать, как это сделать, все еще используя механизм сортировки, встроенный в DataGridView.Если бы я был на вашем месте, я бы, вероятно, просто изменил SortMode каждого столбца на «Programmatic», а затем обработал бы «ColumnHeaderMouseClick» самостоятельно.В этот момент вы должны вызвать метод сортировки в вашем модифицированном классе BindingList, который будет выполнять сортировку по мере необходимости в зависимости от того, по какому столбцу был нажатЭто позволяет избежать использования метода сортировки DGV и сортирует базовый список напрямую.
Полный дискурс Расположен в разделе комментариев.Первоначальный ответ следует немедленно:
РЕДАКТИРОВАТЬ: Из-за некоторой путаницы в отношении проблемы и последующего обсуждения ее, у меня есть новое предложение в комментариях к этому ответу.Я оставляю оригинальный ответ, который я разместил, чтобы мы могли сослаться на него.
Мне недавно пришлось это сделать - и я не буду лгать, это была настоящая боль.Я пришел к решению (с помощью некоторых друзей здесь, в SO), так что здесь идет.Я создал новый интерфейс на основе IComparer, который позволяет указывать как столбец, так и направление.Я сделал это только потому, что мне нужно, чтобы мой код сортировки был как можно более универсальным - у меня есть ДВА сетки, которые нужно сортировать таким образом, и я не хочу поддерживать код дважды.Вот интерфейс, довольно простой:
public interface IByColumnComparer : IComparer
{
string SortColumn { get; set; }
bool SortDescending { get; set; }
}
Очевидно, что если вы не беспокоитесь о том, чтобы сохранить что-то общее (вам, вероятно, следует), то это не является строго обязательным.Затем я создал новый класс, основанный на BindingList <>.Это позволило мне переопределить код сортировки и предоставить свой собственный IByColumnComparer для столбцов за столбцами , что позволило добиться необходимой гибкости.Проверьте это:
public class SortableGenericCollection<T> : BindingList<T>
{
IByColumnComparer GenericComparer = null;
public SortableGenericCollection(IByColumnComparer SortingComparer)
{
GenericComparer = SortingComparer;
}
protected override bool SupportsSortingCore
{
get
{
return true;
}
}
protected override bool IsSortedCore
{
get
{
for (int i = 0; i < Items.Count - 1; ++i)
{
T lhs = Items[i];
T rhs = Items[i + 1];
PropertyDescriptor property = SortPropertyCore;
if (property != null)
{
object lhsValue = lhs == null ? null :
property.GetValue(lhs);
object rhsValue = rhs == null ? null :
property.GetValue(rhs);
int result;
if (lhsValue == null)
{
result = -1;
}
else if (rhsValue == null)
{
result = 1;
}
else
{
result = GenericComparer.Compare(lhs, rhs);
}
if (result >= 0)
{
return false;
}
}
}
return true;
}
}
private ListSortDirection sortDirection;
protected override ListSortDirection SortDirectionCore
{
get
{
return sortDirection;
}
}
private PropertyDescriptor sortProperty;
protected override PropertyDescriptor SortPropertyCore
{
get
{
return sortProperty;
}
}
protected override void ApplySortCore(PropertyDescriptor prop,
ListSortDirection direction)
{
sortProperty = prop;
sortDirection = direction;
GenericComparer.SortColumn = prop.Name;
GenericComparer.SortDescending = direction == ListSortDirection.Descending ? true : false;
List<T> list = (List<T>)Items;
list.Sort(delegate(T lhs, T rhs)
{
if (sortProperty != null)
{
object lhsValue = lhs == null ? null :
sortProperty.GetValue(lhs);
object rhsValue = rhs == null ? null :
sortProperty.GetValue(rhs);
int result;
if (lhsValue == null)
{
result = -1;
}
else if (rhsValue == null)
{
result = 1;
}
else
{
result = GenericComparer.Compare(lhs, rhs);
}
return result;
}
else
{
return 0;
}
});
}
protected override void RemoveSortCore()
{
sortDirection = ListSortDirection.Ascending;
sortProperty = null;
}
}
Теперь, как вы можете видеть в методе ApplySortCore, я получаю столбец и направление непосредственно из DataGridView - это означает, что я не вызываю это программно.Это не похоже на то, что вы хотите сделать, но вы можете легко изменить этот код, если вам нужно вызвать его программно и передать соответствующий IByColumnComparer.Я хочу показать вам все это, чтобы вы могли понять, как изменить алгоритм сортировки, что весьма полезно.
Особая благодарность @MartinhoFernandes за предложения относительно того, как сделать этот класс более универсальным.