• ベストアンサー

ListView_DeleteItemの挙動

リストビューでチェックされた項目を削除したくて下のようなプログラムを書いたのですがうまくいきません どうもListView_DeleteItemに問題があるらしいのは分かるのですが、それ以上のことが分かりません どなたかご教授お願いします index = ListView_GetItemCount(hList); for(i=0;i<index;i++){ if(ListView_GetCheckState(hList,i) != 0){ ListView_DeleteItem(hList,i); } }

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

  • ベストアンサー
noname#15691
noname#15691
回答No.1

index = ListView_GetItemCount(hList); for(i = 0; i < index; i++) { if(ListView_GetCheckState(hList, i) != 0) { ListView_DeleteItem(hList, i); i--; index--; } } 項目を削除すると項目数が1つ減るので、カウンタ(i)と項目数(index)も1つ減らさなければなりません。

kamikorosama
質問者

お礼

ありがとうございます 無事成功しました

関連するQ&A

  • ListViewの複数項目削除で意図しない挙動

    前回質問した内容でほとんど複数削除は解決したように 見えたのですが、どういう条件か分からないのですが 複数選択(1件選択の場合は発生しない)して削除ロジックを 実行すると選択している項目と異なる内容の配列(ArrayList)の データを削除してしまうという事が発生します。 これは何が原因で発生しているのでしょうか? またこれの解決法をご教授頂けないでしょうか。 環境はVS2005(C#)、.NET Framework2.0です。 以下に該当部分のコードを載せます。 2000文字を超えてしまったので問題の部分以外は省略しました。 ※添付画像が見にくかったので以下のURLに再掲示しましたので 参考にしてもらえるとありがたいです。 http://angelteatime.punyu.net/questionbox_20090312.jpg 画像では350件ある受信メール(ArrayListに1件ずつMailクラスで 格納されている)の先頭から8件ぐらい選択削除をしようとしている 画面です。 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) { int nIndex = (int)listView1.Items[sel_index].Tag; if (listView1.Items[sel_index].SubItems[1].Text == ((Mail)collectionMail[RECEIVE][nIndex]).subject) { collectionMail[DELETE].Add(collectionMail[RECEIVE][nIndex]); collectionMail[RECEIVE].RemoveAt(nIndex); } else{ MessageBox.Show(string.Format("選択した件名と削除するデータが異なっています。\nリスト位置件名:{0}\n実位置件名:{1}\n(リスト位置:{2}, 実位置:{3}", listView1.Items[sel_index].SubItems[1].Text, ((Mail)collectionMail[RECEIVE][nIndex]).subject, sel_index, nIndex), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } this.textBody.Text = ""; } else if(listView1.Columns[0].Text == "宛先"){ (上記のRECEIVEがSENDに変更のみでロジック変更なし) } else if(listView1.Columns[0].Text == "差出人または宛先"){ (上記のDELETEに変更されDELETEの配列に格納されたデータを削除) } // ツリービューとリストビューの表示を更新する UpdateTreeView(); UpdateListView(); (ListViewのフォーカスを設定し直す) }

  • ListViewの項目を入れ替える

    C++で詳細表示のリストビューを扱うプログラムを書いているのですが あるボタンを押すと選択した項目が上や下に移動するようにしたいんです そのためには選択した項目とその上下の項目を入れ替えたらいいと思うのですが やり方がわかりません ListView_SortItemsマクロを使ってみましたが、ある二つの項目だけを入れ替えるのは できなさそうです。 MFCを使わない方法があればうれしいです

  • 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(); } } }

  • ListViewとArrayListの連動がうまくいきません

    メールソフトの中で既読、未読を設定するフラグを実装しているのですが ListViewのカラムクリック時の昇順・降順設定を追加するとなぜか おかしな表示になってしまいます。 未読(フラグがtrue)の時は太字で表示されて、既読(フラグがfalse)の 場合は通常のフォントで表示するようにしてあるのですが、 指定している配列ですべてtrueにしているのにもかかわらず表示されるのは trueとfalseの結果の表示がまばらに出てしまって何が原因なのかが 分かりません。 どうすればこれを解決する事が出来るでしょうか? 環境はVS2005(C#)、.NET Framework 2.0です。 リストビューの昇順・降順ロジックはどぼんの.NET Tipsに 載っている文字列、数字、日付で比較が可能なタイプのを 使用しています。 public void UpdateListView() { ArrayList list = null; int i = 0; if (listView1.Columns[1].Text == "差出人") { // 受信メールの場合 list = collectionMail[RECEIVE]; } else if (listView1.Columns[1].Text == "差出人または宛先") { // 削除メールの場合 list = collectionMail[DELETE]; } listView1.BeginUpdate(); // リストビューの内容をクリアする listView1.Items.Clear(); // ListViewを設定する foreach (Mail mail in list) { ListViewItem item = new ListViewItem(mail.subject); item.SubItems.Add(mail.address); item.SubItems.Add(mail.date); // この2行を追加 item.Tag = i; i++; listView1.Items.Add(item); // 未読(未送信)の場合は、フォントを太字にする int index = listView1.Items.Count - 1; if (mail.notReadYet == true) { listView1.Items[index].Font = new Font(this.Font, FontStyle.Bold); } } listView1.EndUpdate(); } private void listView1_DoubleClick(object sender, EventArgs e) { Mail mail = null; ListViewItem item = listView1.SelectedItems[0]; if (listView1.Columns[1].Text == "差出人") { mail = (Mail)collectionMail[RECEIVE][(int)item.Tag]; } else if (listView1.Columns[1].Text == "差出人または宛先") { mail = (Mail)collectionMail[DELETE][(int)item.Tag]; } mail.notReadYet = false; textBox1.Text = mail.body; UpdateListView(); } private void Form1_Load(object sender, EventArgs e) { // ListViewにアイテムを追加する for (int no = 0; no < subject.Length; no++) { Mail mail = new Mail(subject[no], address[no], date[no], body[no], read[no]); collectionMail[RECEIVE].Add(mail); } UpdateTreeView(); UpdateListView(); // ListViewItemComparerの作成と設定 listViewItemSorter = new ListViewItemComparer(); listViewItemSorter.ColumnModes = new ListViewItemComparer.ComparerMode[] { ListViewItemComparer.ComparerMode.String, ListViewItemComparer.ComparerMode.String, ListViewItemComparer.ComparerMode.DateTime }; // ListViewItemSorterを指定する listView1.ListViewItemSorter = listViewItemSorter; }

  • VB6 API LISTVIEW(チェックボックス付き)にチェックを付けたい

    CreateWindowExでLISTVIEW(チェックボックス付きのレポートビュー)を作ったのですが、「山田花子」行にソースでチェックを付ける方法が分かりません。 Form1のソース ↓ Option Explicit Private Sub Form_Load() Dim lngRet As Long Dim lvcol As LV_COLUMN Dim rStyle As Long Dim item As LV_ITEM '-- リストビューの作成 hList = CreateWindowEx(WS_EX_CLIENTEDGE, _ WC_LISTVIEW, "", _ WS_CHILD Or WS_VISIBLE Or WS_BORDER Or _ WS_CLIPSIBLINGS Or WS_CLIPCHILDREN Or _ LVS_REPORT, _ 0&, 0&, Me.ScaleWidth / Screen.TwipsPerPixelX, 200&, _ Me.hwnd, _ 0&, _ App.HINSTANCE, _ ByVal 0&) '拡張スタイルを設定 rStyle = rStyle Or LVS_EX_FULLROWSELECT Or LVS_EX_GRIDLINES Or LVS_EX_CHECKBOXES SendMessageByNum hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0&, rStyle '-- カラムヘッダーの追加 With lvcol .mask = LVCF_FMT Or LVCF_WIDTH Or LVCF_TEXT Or LVCF_SUBITEM .fmt = LVCFMT_LEFT .cx = 100 .pszText = "名前" .iSubItem = 0 lngRet = ListView_InsertColumn(hList, 0&, lvcol) End With '-- リストアイテムの追加 With item .mask = LVIF_TEXT Or LVIF_IMAGE ' 1つめ .pszText = "山田 太郎" .iItem = 0 .iSubItem = 0 .iImage = 0 lngRet = ListView_InsertItem(hList, item) ' 2つめ .pszText = "山田 花子" .iItem = 1 .iSubItem = 0 .iImage = 1 lngRet = ListView_InsertItem(hList, item) End With End Sub Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) '-- リストビューを破棄 DestroyWindow hList End Sub 標準モジュールは補足に書きます

  • ListViewについて

    いつもお世話になっています。 タイトルの通り、ListViewについて2つ質問があります。 (1)ListViewにDBから検索したデータを代入してますが、動きが遅いんです。  各項目ごとで色を変更したりするためだと思いますが、ListViewの表示を速くする方法はなにかありませんか?  ちなみに今は、ListViewを2枚使って、データをセットしている間は、VisibleをFalseにして、  データセットが完了した時点で、Trueに切り替えています。 (2)(1)の動きで、ListViewを使っているところ、今表示されているListView(Iとします)で  クリックしたデータを次に表示させるListView(IIとします)に引き継がせたいです。  Iで、選択している行をIIで選択状態にすることはできたのですが、  Iで選択している行がスクロールして下にあった場合、IIでもスクロールした場所に  ListViewを移動させたいのですが、その方法が分かりません。 何かご存知の方がいましたら、教えてください。 よろしくお願いいたします。

  • ListViewで、PageDownキーイベントを発生させるには?

    VB6で開発しています。 ラベルとListViewのみのフォーム上で、 PageUpやPageDownキー押下で、イベントを発生させたいのですが、 PageDownを押下すると、ListView内のリストのカーソルが下に移動してしまい、 (フォーカスが当たるコントロールがListViewしかないためと思われますが) イベントが発生せずに困っています。 自分で実現しようとしてできなかった方法を紹介します ・リストビューにフォーカスが当たらないようにする。   Enabled = Falseだとスクロールバーが使えないので困る。    ・ListViewはEnabled=Falseにし、スクロールバーコントロールを使って、スクロールさせる。   スクロールさせる方法が見つかりませんでした。 何か、よいアイデアや方法があれば、ご教授宜しくお願いしますm(_ _)m

  • checkbox付きListViewで デフォルトチェック

    チェックボックス付きのListViewコントロールで初期値としてチェックボックスにチェック をして表示したいと思っております。 Listviewにデータを追加して(subitemもあるため)その後 ListView1.Item(i).Selected = True をしているのですが、チェックして表示されません。 項目が表示された後、何れかの項目をチェックしようとするとチェックが表示されます。 どのようにすれば最初から表示されるのでしょうか? 初歩的な質問かもしれませんが、お願い致します。

  • リストビューで選択行の背景を変える

    お世話になります。リストビューの選択行の背景色を変えたいと思い、カスタムドローを用い以下のようにしましたが、選択していない所も赤になってしまいます。 if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) {  // 選択行の背景色を変更  if (lplvcd->nmcd.uItemState & CDIS_SELECTED) {   lplvcd->clrTextBk = RGB(255, 0, 0);   lplvcd->nmcd.uItemState &= ~CDIS_SELECTED;  } else {   lplvcd->clrTextBk = RGB(255, 255, 255);  }  return CDRF_NOTIFYSUBITEMDRAW; } デバッグモードで見ると、else以降の分は解釈されていないようです。 リストビューは g_hList = CreateWindowEx(0 , WC_LISTVIEW , 0 , WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_NOSORTHEADER | LVS_SHOWSELALWAYS, 1 , 1 , width , lv_height , g_hMain , (HMENU)1 , g_hInst , NULL); dwStyle = ListView_GetExtendedListViewStyle(g_hList); dwStyle |= LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES; ListView_SetExtendedListViewStyle(g_hList, dwStyle); ListView_SetBkColor(g_hList, RGB(240,240,240)); のようにしています。宜しくお願いします

  • ListViewのカラムの色の変更

    色々と探したり試したりしたのですが、BCBのリストビューの カラムの背景色変更ができません。 ListViewのCustomDrawItemでCanvasを使用すると リストの項目の背景色は変更できるのですが、カラムの色は変更できないのでしょうか? http://www.mitene.or.jp/~sugisita/vb6_cmctl.html 上記ページで”リストビューのカラムヘッダの色変更”で できるような事をBCBで行いたいのですが… アドバイスお願いいたします。