VisualStudioのDataGridViewでデータをソートしたり、行の順番を入れ替えたりする場合、Insertで空白行を追加して内容をコピーしたり、RemoveAtでコピー元の行を消したりしてしまうと、処理時間がめちゃくちゃかかる(おそらく内部的に行がズレた分のコピペを繰り返しているのだろう・・・)
そんな時の対応策を歴2カ月の素人が作ってみたので、自分用にメモ
<手順>
1)行を消すのは全消しであるdataGridView.Rows.Clear()が圧倒的に早いのでこれを活用する
2)最初に全消しできないので、とある列の内容に従って並び替えするとして、内容と行インデックスを紐付けて並び替える必要がある。以下リンクを参考にしました。
3)並び替え後のインデックスをQueueに格納する
(わざわざ新しいインデックスを付ける必要がなくなる)
4)2次元配列のような入れ子型のlistで、並び替え後の行列の内容を全て変数に格納する
以下リンクを参考にしました。
5)Rows.Clearで全消しして、入れ子型のlistから1行ずつRows.Addで登録していく
private void button7_Click_2(object sender, EventArgs e)
{
全工程表示btn.PerformClick();
//OP_NoとOP追番の合計が最も小さい行のインデックスを探す
List<int> list = new List<int>();
for (int i = 0; i < processGridView.Rows.Count; i++)
{
string OP1 = processGridView[7, i].Value.ToString();
string OP2 = processGridView[8, i].Value.ToString();
int intOP1 = 0;
int.TryParse(OP1, out intOP1);
int intOP2 = 0;
int.TryParse(OP2, out intOP2);
int No = intOP1 * 100 + intOP2;
list.Add(No);
}
//listの数値が小さい順に、そのインデックスをキューに格納
Queue<int> queue = new Queue<int>();
var sorted = list.Select((x, i) => new KeyValuePair<int, int>(x, i)).OrderBy(x => x.Key);
foreach (KeyValuePair<int, int> kv in sorted)
{
queue.Enqueue(kv.Value);
}
//元の小さい順のグリッドの内容を2次元リストに保存
List<List<string>> Col = new List<List<string>>();
while (queue.Count > 0)
{
List<string> Row = new List<string>();
int rowIndex = queue.Dequeue();
for (int i = 0; i < processGridView.ColumnCount; i++)
{
Row.Add(processGridView[i, rowIndex].Value.ToString());
}
Col.Add(Row);
}
//表示されている全行を削除
processGridView.Rows.Clear();
//格納した入れ子listを1行ずつAdd
for(int i = 0; i < Col.Count; i++)
{
processGridView.Rows.Add(Col[i].ToArray());
}
processGridViewReadOnly();
}