設定
カスタム IComparer を使用して DataGridView を並べ替えるコードがあります。
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 がありません。行は手動で追加されています。
- エラーのスタック トレースの深さは 1 レベルのみです。mscorlib の InternalDictionary で発生します。
- 奇妙な事実 #1 - これは、任意の時点で、カスタム比較子がその比較のいずれかに対して -1 を返す場合にのみ発生します
- Sort メソッドを変更して CustomComparer を使用しないようにすると、例外はスローされません。
回避策
この最後の事実により、Compare() メソッドを書き直して、.NET の CompareTo メソッドに従うようにしました。
DataGridViewRow row1 = (DataGridViewRow)x;
DataGridViewRow row2 = (DataGridViewRow)y;
return row1.ReadOnly.CompareTo(row2.ReadOnly);
これは不思議なことに機能しました。例外はスローされなくなりました。
したがって、回避策はありますが、なぜこれが修正される可能性があるのか 、そもそも何が問題だったのか、誰かが知っているのではないかと思います. CompareTo の実装を見てきましたが、 -1も返されます...