Настраивать
У меня есть фрагмент кода, который сортирует DataGridView с помощью пользовательского IComparer:
public class CustomComparer: IComparer
{
public int Compare(object x, object y)
{
DataGridViewRow row1 = (DataGridViewRow)x;
DataGridViewRow row2 = (DataGridViewRow)y;
if (row1.ReadOnly && row2.ReadOnly)
{
return 0;
}
else if (row1.ReadOnly && !row2.ReadOnly)
{
return 1;
}
else
{
return -1;
}
}
Проблема
Странно, когда я выполняю следующую строку (после заполнения строк):
grid.Sort(new CustomComparer());
Я получаю исключение ArgumentOutOfRangeException с сообщением «Индекс вышел за пределы допустимого диапазона. Параметр: индекс».
Больше фактов
Дальнейшее расследование выявило следующее:
- DataGridView, который я сортирую, не имеет BindingSource — строки были добавлены вручную.
- Трассировка стека ошибки имеет глубину всего один уровень — она возникает во внутреннем словаре в mscorlib.
- Странный факт № 1. Это происходит только в том случае, если в какой-то момент мой пользовательский компаратор возвращает -1 для любого из своих сравнений.
- Если я изменю метод Sort, чтобы больше не использовать мой CustomComparer, исключение не будет выдано.
Обходной путь
Этот последний факт заставил меня переписать метод Compare(), чтобы он соответствовал методу CompareTo .NET:
DataGridViewRow row1 = (DataGridViewRow)x;
DataGridViewRow row2 = (DataGridViewRow)y;
return row1.ReadOnly.CompareTo(row2.ReadOnly);
Что таинственным образом сработало. Исключение больше не выбрасывается.
Поэтому, хотя у меня есть обходной путь, мне интересно, есть ли у кого-нибудь идеи, почему это может быть исправлением, и в чем проблема могла заключаться в первую очередь. Я просмотрел реализацию CompareTo, и она также возвращает -1...