none
CLRでのリストビューのアイテムのテキストの取得と、行の編集 RRS feed

  • 質問

  • よろしくお願いします。

    .NET2005 VISTA です。

     

    CLRで、リストビューのアイテムとサブアイテムのテキストを取得する方法をお教えください。

    また、たとえばリストビューが10行5列だった場合に、途中の行(たとえば5行目)を削除、テキストを上書き修正、1行挿入、

    の方法をお教えください。

     

    「くぐった」のですが、該当するページを見つけられませんでした。

     

    できましたら、コードをご提示いただければ、幸いです。

     

     

     

    手元にある参考書では、

     

    myItem = gcnew ListViewItem();
    myItem->Text = L"あ";
    myItem->SubItems->Add(L"い");

     

    というように、リストビューを描画する時、次々に新しい行を追加する形で、追加する行の番号は指定していません。 
    リストビューの一部を編集する場合、リストビュー全体を書き換える方が、一般的なのでしょうか。

    2008年2月8日 19:55

すべての返信

  •  初々心者 さんからの引用

    「くぐった」のですが、該当するページを見つけられませんでした。

    ぐる」とは、Googleで検索することです。

    http://www.google.co.jp/

     

     初々心者 さんからの引用

    できましたら、コードをご提示いただければ、幸いです。

    コードのコピペは身につきませんので、コードは提示しません。

    検索のコツを掴んで、自分が欲しい情報を見つけられるようになってください。

     

    コントロールに対する操作方法について、「C++」や「CLR」で検索することは情報量を減らすだけなので辞めた方が良いです。

    当然、C#やVB.NETでの記述が多くなります。C++/CLI(CLR)の流儀に従って書き換える必要があります。

     

     初々心者 さんからの引用

    CLRで、リストビューのアイテムとサブアイテムのテキストを取得する方法をお教えください。

    検索キーワードは「ListView SubItem」

    http://dobon.net/vb/bbs/log3-12/7132.html

     

     初々心者 さんからの引用

    また、たとえばリストビューが10行5列だった場合に、途中の行(たとえば5行目)を削除、テキストを上書き修正、1行挿入、

    の方法をお教えください。

    検索キーワード「ListView 削除」

    http://msdn2.microsoft.com/ja-jp/library/2fds7919(VS.80).aspx

     

    検索キーワード「ListView Item 書き換える」

    http://hanatyan.sakura.ne.jp/dotnet/ListVie2.htm

     

    検索キーワード「ListView ListViewItem 位置 挿入」

    http://msdn2.microsoft.com/ja-jp/library/xf54248d(VS.80).aspx

     

     

    最後にヘルプのListViewクラスのメンバーはご覧になりましたか?

    一覧を眺めるだけでもヒントを得られることがあります。

    今回の場合、Itemsプロパティの先にListViewItemCollectionやListViewItem、SubItemsプロパティの先のListViewSubItemsCollectionやListViewSubItemのヘルプを読みあさることで「キーワード」を得ることができるかと思います。

    2008年2月8日 23:44
    モデレータ
  • ところで List< T> は、使いこなせているのでしょうか?

    2008年2月9日 1:19
  • 行の削除は、

    Code Snippet

    listView1->Items->RemoveAt(Index);

     

     

    で、できました。

     

    追加も、

    Code Snippet

    ListViewItem^ myItem = gcnew ListViewItem();
    myItem->Text = L"item0";
    listView1->Items->Insert(2, myItem);
    myItem->SubItems->Add(L"item1");

     

     

    で、できました。

     

    ありがとうございました。

     

    しかし、それ以外は、C++に置き換えることができません。

     

    上書き修正について、ご提示のコード

    Code Snippet
    ListView1.Items(1).SubItems(0).Text = "蚊取  新語";

     

     

    をアロー演算子に置き換え、

    Code Snippet

    listView1->Items(1)->SubItems(0)->Text = L"蚊取  新語";

     

     

    とし、リビルドすると、

     

     1 引数を取り込む関数には評価されません。
    左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。
     : 左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。

     

    というエラーになります。

     

     

    アイテムのテキストの取得についても、

    Code Snippet
    ListView.ListViewItemCollection lvic = リスト1.Items;
    ListViewItem lvi = lvic[0];

     

     

    の置き換え方が分かりません。

     

    Code Snippet
    ListViewItemCollection lvic = listView1->Items;
    ListViewItem lvi = lvic[0];

     

     

    とすると、

     

    ';' が、識別子 'lvic' の前に必要です。
    'lvic' : 定義されていない識別子です。

     

    というエラーになります。


     

    2008年2月9日 3:27
  • Abstractさん、その節はたいへんお世話になり、ありがとうございました。

     

    > ところで List< T> は、使いこなせているのでしょうか?

     

    そう言われると、逆に心配になったりします。

    特に支障なく値の出し入れをしているつもりなのですが。。。

    なにか問題があるのでしょうか。

     

    変数をprivateにできるようになって、ちょっと落ち着いた気がします。

     

     

    2008年2月9日 3:36
  • List< T> でも ListViewSubItemCollection でも、とにかく IList を実装(つまり継承)しているクラスは、
    Add で末尾への要素の追加。
    RemoveAt で、特定のインデックスの要素を削除。
    Insert で、特定のインデックスに要素を挿入。
    Item で、特定のインデックスの要素を取得or設定。
    .
    .
    .
    といった、共通の動作をするという事を言いたかったのです。
    既に理解しておられるなら良いのです。

     

    2008年2月9日 4:16
  • 外池と申します。

     

    Itemで特定のインデックスの要素を取得or設定する際、Itemは、いわゆる「Default」のプロパティーであって、Itemの文字は省略できて、いきなりインデックスをもって来ればよいのですが、C++/CLIの場合、インデックスを囲むのは、( )ですか? [ ]ですか?

    2008年2月9日 5:00
  • Abstractさん、ありがとうございました。

    解決しました。

     

    アイテムのテキストの上書きは、

     

    listView1->Items[Index]->SubItems[0]->Text = L"0列";
    listView1->Items[Index]->SubItems[1]->Text = L"1列";

     

    で、

     

    テキストの取得は、右辺と左辺を逆にすることで、成功しました。

     

    重ねて申し訳ありませんが、1点教えてください。

    0列で、

    listView1->Items[2]->Text = L"0列";

    でも、同じ結果になったのですが、これは、

    listView1->Items[Index]->SubItems[0]->Text = L"0列";
    と、どちらが better でしょうか。

    それとも、「たいした違いはない」というレベルの話なのでしょうか。

     

     

    2008年2月9日 5:21
  • 外池です。

     

    SubItemのTextだけをつかっている分には、0列を使ってもよいかもしれませんが、まぁ、やめたほうがいいでしょう。ドキュメントにはSubItemについては1列から使え、と書いてあるし・・・。

     

    理由は、SubItemの他のプロパティーを使う場合には0列は別の意味をもってくることがあるからで。

     

    -----

     

    しかし・・・、

     

    「このフォーラムで教えてもらって書いたらプログラムガ動くようになりました」というのは、不安なものですよ。「教えてもらったドキュメントや書籍を読んで、納得できて、自分なりに考えてプログラムを書いたら確かに意図したとおりに動きました」じゃないと、そのプログラムは使えないです。

     

    2008年2月9日 5:39
  •  初々心者 さんからの引用

    アイテムのテキストの取得についても、

    Code Snippet
    ListView.ListViewItemCollection lvic = リスト1.Items;
    ListViewItem lvi = lvic[0];

     

     

    の置き換え方が分かりません。

     

    Code Snippet
    ListViewItemCollection lvic = listView1->Items;
    ListViewItem lvi = lvic[0];

     

     

    とすると、

     

    ';' が、識別子 'lvic' の前に必要です。
    'lvic' : 定義されていない識別子です。

     

    というエラーになります。

     

    その前に「'ListViewItemCollection' : 定義されていない識別子です。」 というエラーが発生するはずです。

    'ListViewItemCollection' という名前のクラスが存在しないとコンパイラに怒られています。

    名前空間(namespace)を考慮にいれてください。

    他にもう1点間違ってますが、一つずつ解決してください。

    2008年2月9日 5:47
  •  外池 さんからの引用

    Itemは、いわゆる「Default」のプロパティーであって、

    今思えば、Item は他のメンバと比べて特殊で、例に出すのは問題がありましたね。

     

    #言語によってデフォルト プロパティの意味が微妙に違っている気がする……

    2008年2月9日 6:15
  • 外池です。長文になりますが・・・、

     

    Defaultというのが、クラスライブラリー側の視点でのメンバーの特徴を示したものと理解するなら、つまり、Defaultと修飾されているメンバーはメンバー名を省略して呼び出すことができるとクラスライブラリー側で規定していると理解するなら、言語によって特に意味の違いはないと思うのですが・・・。

     

    こと、コレクションの類(厳密には、IListあるいはIList<T>を実装したクラス)のItemプロパティーに関しては、Itemというメンバー名を省略できるところまでは良いのですが、配列と同じように呼び出せるようにという配慮から、C#とC++/CLIに関して特に引数としてのインデックスを[ ]で囲って呼び出せる(プロパティーの呼び出しに用いる引数は、通常なら( )で囲む)ように細工がしてあるわけですよね? ここは、C#とC++/CLIに関して特殊なところと思います。

     

    特殊でもなんでもないのですが、ListViewに関しては、内容物の集合を現すコレクションのメンバー名自体が「Items」という名前になっていることは、ややこしいところです。Itemsの個々の要素を呼び出すとき、C#とC++/CLIの場合は、上述の省略をしないならItems.Item(indx)という呼び出し方になるし、省略をするならItems[indx]という呼び出し方になる。

     

    私も、理解する(知識を得たり、納得したり)のは遅々としているので、あまり偉そうなことは言えませんが、

     

    初々心者さんは「動きました」と一言で済ませられていますが、Abstractさんが仰った、ListView.ItemsとList<T>が類似している(どちらもIListあるいはIList<T>を実装している)こと、IListのItemプロパティーの呼び出し方は上述のとおりであること、こういうことを踏まえつつ、C.Johnさんが仰るとおり、ひとつ、ひとつ進めていくべきであること、を、注意喚起しておきたいと思います。

     

    最初コンパイルが通らないソースがあって、修正したら通った。そのときは、すべての修正について、何が間違っていたのか、動くようになった正しい書き方はドキュメントのどこに書いてあるのか、把握しておくべきです。そうすれば、同じ間違いはしません。把握しないままだと、一度遭遇したことなのに再び試行錯誤をしてしまいます。

     

    コンパイルが通るようになっても、ロジックの誤りで正しい動作が得られないことも多々ありますが、それこそ、対症療法的にいじってなんとなく動くようになったソフトなぞ、使えたものではありません。そして、このトラブルシューティングがもっとも難しいところであって、逆に、プログラミングの醍醐味でもあります。

     

    2008年2月9日 9:22
  • 意味の違いを感じたのは、宣言の部分です。

    C++/CLI では、

     

    property int default[int]{ ... }

     

    と書くところを、C# では、

     

    int this[int index]{ ... }

     

    と書くようなので、
    何故 C++/CLI では default で、C# では this なのだろう?

    と思ったわけです。不十分な書き方をして済みません。

     

    別の例を挙げるなら、
    VB における「共有(Shared な)メソッド」と、
    他の言語の「静的(static な)メソッド」がありますね。

     

    まぁ言語レベルの違いに過ぎませんので、実際書くときには気にしませんけど。

    2008年2月9日 10:49
  • たいへんありがとうございました。

     

    0列のテキストを取得する際には、

     

    ListViewItem^ myItem;
    myItem->Text

     

    を使います。

    2008年2月9日 20:21