howling さん、shu さん
失礼しました。
中途半端に終わらせたこと、お詫びします。
また、皆様に間違った情報をお見せしていたことをお詫びします。
NullReferenceException が出る箇所は
if (fn == r.Cells["FileName"].Value.ToString()) {
の行なので、lst が null だと言って例外を出しているのではないようです。
結論から言いますと、null であるのは r.Cells["FileName"].Value.ToStoring() です。
DataGridView の AllowUserToAddRows プロパティが true の場合に Rows を使って
foreach をすると、末尾に付いている新規行までループが回るようです。
また、AllowUserToAddRows が ture の場合、RowCount プロパティは現在の行数 + 1 になる
ようです。データベース上のレコード数と DataGridView 上の行数が 1 違ってしまうという
ことになりますね。
ですので、AllowUserToAddRows が true の場合に foreach を使ってはダメだと言えそうです。
for を使って、
for (int r = 0; r < dgv.RowCount - 1; ++r) で回さないと、行の追加用の行まで
見に行って、そこは当然全カラムが null なのでその値を使おうとすると NullReference
ということのようです。
試しに AllowUserToAddRows を false にしたところ、意図したとおりに動きました。
ユーザーに新規レコードの追加を許可したい場合は全行ループは for 文を使って最後の行まで
行かないように走査しないといけません。
質問の最初から最後まで思い違いばかりしていたようです。
howling さん、shu さんにはたいへん感謝しています。
実は諦めて try - catch で握りつぶしていました。
「解決済み」のあとのお二人のレスがなかったら、そのまま行っているところでした。
2つのケースのコードです。
// DataGridView の AllowUserToAddRows が true の場合
// fnlist:List<string>
// b:bool
// fnames:List<string>
foreach (var fn in fnlist) {
b = false;
// 追加用の行があるので for 文でこのように。
for (int r = 0; r < dgv.RowCount - 1; r++) {
if (fn == dgv.Rows[r].Cells["FileName"].Value.ToString())
b = true;
break;
}
}
if (!b) {
fnames.Add(fn);
}
}
// DataGridView の AllowUserToAddRows が false の場合
// fnlist:List<string>
// b:bool
// fnames:List<string>
foreach (var fn in fnlist) {
b = false;
// 普通に foreach で OK
foreach (DataGridViewRow r in dgv.Rows) {
if (fn == r.Cells["FileName"].Value.ToString()) {
b = true;
break;
}
}
if (!b) {
fnames.Add(fn);
}
}
|