こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ListViewの複数項目削除で再度質問です

ArrayListのソートの件とListViewのおかしな挙動は解決できたのですが
最初に質問して解決したはずの削除の部分で再び分からなくなって
しまったので質問させて頂きます。

今回は本体に今までのコードを正式に組み込んで、動作の確認を
行っていたのですが、複数件(連続や個別選択)のデータ削除を
行おうとしたら意図しないデータ(未整列状態の並びのデータ)が
削除されてしまうという事態が発生してしまいました。

これはどうすれば解決できるのでしょうか?
また複数件の未読既読を制御(選択された項目に対してフラグを
入れ替える)するのも同様の方法で出来るのでしょうか?

環境はVS2005(C#)、.NET Framework2.0です。

以下に問題の削除時のコードを載せます。
private void menuDelete_Click(object sender, EventArgs e)
{
// 選択アイテムが0のときは反応にしない
if(listView1.SelectedItems.Count == 0){
return;
}

if(listView1.Columns[0].Text == "差出人"){
// 受信メールのとき
for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) {
if (listView1.Items[sel_index].Selected) {
collectionMail[DELETE].Add(collectionMail[RECEIVE][sel_index]);
collectionMail[RECEIVE].RemoveAt(sel_index);
}
}
this.textBody.Text = "";
}
else if(listView1.Columns[0].Text == "宛先"){
// 送信メールのとき
for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) {
if (listView1.Items[sel_index].Selected) {
collectionMail[DELETE].Add(collectionMail[SEND][sel_index]);
collectionMail[SEND].RemoveAt(sel_index);
}
}
this.textBody.Text = "";
}
else if(listView1.Columns[0].Text == "差出人または宛先"){
// 削除メールのとき
if(MessageBox.Show("選択されたメールは完全に削除されます。\nよろしいですか?", "確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK){
for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) {
if (listView1.Items[sel_index].Selected) {
collectionMail[DELETE].RemoveAt(sel_index);
}
}
this.textBody.Text = "";
}
}

// ツリービューとリストビューの表示を更新する
UpdateTreeView();
UpdateListView();

// 選択している位置がリストの件数よりも少ないとき
if(currentRow < listView1.Items.Count){
// 選択していた位置-1の行にフォーカスを当て直す
listView1.Items[currentRow - 1].Selected = true;
listView1.Items[currentRow - 1].Focused = true;
listView1.SelectedItems[0].EnsureVisible();
listView1.Select();
listView1.Focus();
}
else{
// リストの件数が1以上の時
if(listView1.Items.Count > 0){
// ListViewの行数位置-1の行にフォーカスを当て直す
listView1.Items[listView1.Items.Count - 1].Selected = true;
listView1.Items[listView1.Items.Count - 1].Focused = true;
listView1.SelectedItems[0].EnsureVisible();
listView1.Select();
listView1.Focus();
}
}
}

投稿日時 - 2009-03-11 15:10:45

QNo.4787629

すぐに回答ほしいです

質問者が選んだベストアンサー

ListViewのItemsのIndexと collectionMailリストのインデックスが同じ物を指しているかが問題なのでしょう

ListからListViewItemを登録する際にListViewItemのTagプロパティにListのインデックスを登録しておきます

削除する際には
for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) {
  if (listView1.Items[sel_index].Selected) {
    int nIndex = (int)listView1.Items[sel_index].Tag
    collectionMail[DELETE].Add(collectionMail[RECEIVE][nIndex]);
    //collectionMail[RECEIVE].RemoveAt(sel_index);
    // 削除済みとして -にしてマークしておく
    listView1.Items[sel_index].Tag = -nIndex;
    collectionMail[RECEIVE][nIndex].DeleteFlag = true;
  }
}
としてみてはいかがでしょう

ArrayListから登録する際にも
foreach( Mail mail in list ) {
  // フラグをみてリストを追加
  if ( !mail.DeleteFlag ) {
    ListViewItem Item = new ListViewItem( mail.subject );
    Item.SubItems.Add( mail.Address );
    // ... その他のデータをついか
  }
}

データをファイルに落とす際に DalateFlagがついてない物だけ書き込むようにする
等の対策でどうでしょう ...

投稿日時 - 2009-03-11 18:23:27

補足

うーん、個人的にはRECEIVEリストから削除して、削除分を
DELETEリストに移動するという処理だけで良いと思うのですが・・・。
→元々のプログラムに出来るだけ手を加えないようにしています。

これだと間違った項目を消してしまう可能性があるんですよね。
→何度か試してみて何回か削除するものが異なっていた。

private void menuDelete_Click(object sender, EventArgs e)
{
// 選択アイテムが0のときは反応にしない
if(listView1.SelectedItems.Count == 0){
return;
}

if(listView1.Columns[0].Text == "差出人"){
// 受信メールのとき
for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) {
if (listView1.Items[sel_index].Selected) {
// collectionMail[DELETE].Add(collectionMail[RECEIVE][sel_index]);
// collectionMail[RECEIVE].RemoveAt(sel_index);
int nIndex = (int)listView1.Items[sel_index].Tag;
collectionMail[DELETE].Add(collectionMail[RECEIVE][nIndex]);
collectionMail[RECEIVE].RemoveAt(nIndex);
}
}
this.textBody.Text = "";
}
else if(listView1.Columns[0].Text == "宛先"){
// 送信メールのとき
for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) {
if (listView1.Items[sel_index].Selected) {
// collectionMail[DELETE].Add(collectionMail[SEND][sel_index]);
// collectionMail[SEND].RemoveAt(sel_index);
int nIndex = (int)listView1.Items[sel_index].Tag;
collectionMail[DELETE].Add(collectionMail[SEND][nIndex]);
collectionMail[SEND].RemoveAt(nIndex);
}
}
this.textBody.Text = "";
}
else if(listView1.Columns[0].Text == "差出人または宛先"){
// 削除メールのとき
if(MessageBox.Show("選択されたメールは完全に削除されます。\nよろしいですか?", "確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK){
for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) {
if (listView1.Items[sel_index].Selected) {
// collectionMail[DELETE].RemoveAt(sel_index);
int nIndex = (int)listView1.Items[sel_index].Tag;
collectionMail[DELETE].RemoveAt(nIndex);
}
}
this.textBody.Text = "";
}
}

// ツリービューとリストビューの表示を更新する
UpdateTreeView();
UpdateListView();

// 選択している位置がリストの件数よりも少ないとき
if(currentRow < listView1.Items.Count){
// 選択していた位置-1の行にフォーカスを当て直す
listView1.Items[currentRow - 1].Selected = true;
listView1.Items[currentRow - 1].Focused = true;
listView1.SelectedItems[0].EnsureVisible();
listView1.Select();
listView1.Focus();
}
else{
// リストの件数が1以上の時
if(listView1.Items.Count > 0){
// ListViewの行数位置-1の行にフォーカスを当て直す
listView1.Items[listView1.Items.Count - 1].Selected = true;
listView1.Items[listView1.Items.Count - 1].Focused = true;
listView1.SelectedItems[0].EnsureVisible();
listView1.Select();
listView1.Focus();
}
}
}

投稿日時 - 2009-03-11 21:22:58

お礼

すみません。
一応この件はもう一度再投稿致します。
やりたい事の半分はできているので次の質問の方で
宜しくお願い致します。

投稿日時 - 2009-03-12 00:59:25

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問