- PR -

[C#] ListViewについて

1
投稿者投稿内容
Syou
会議室デビュー日: 2006/02/03
投稿数: 13
投稿日時: 2006-02-27 13:30
ListViewでわからない部分があるので質問させていただきます

やりたいこと:
1.テキストファイルを開いて1行ずつ読み込む

2.まず、読み込んだ1行を , で区切っていく
3.次にListViewのSubItemに区切った最初の部分をいれる
(↓のソースならreadline[0])
4.2,3の作業を指定したテキストの読み込みが終わるまで連続して行う

やったこと:
 連続して2,3の作業がどうしても思いつかなかったため、以下のようにかなり変な風にしています。(別にlistbox1を作成し、読み込ませそれによって全体のcountを取得)

OpenFileDialog opendlg = new OpenFileDialog();
opendlg.Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*";
opendlg.InitialDirectory = mDefaultDirectory;

if (opendlg.ShowDialog() == DialogResult.OK)
  {
     // ディレクトリを保存しておく
    FileInfo fi = new FileInfo(opendlg.FileName);
    mDefaultDirectory = fi.DirectoryName;

    // ファイルを読み込む
    Stream stm = opendlg.OpenFile();
    filePath = opendlg.FileName;

    //一度すべてクリア
    listView1.Items.Clear();

    if (stm != null)
      {
        StreamReader reader = new StreamReader(stm,System.Text.Encoding.GetEncoding("Shift_JIS"));

        while (reader.Peek() > -1)
        {
          listBox1.Items.Add(reader.ReadLine());
          kugiri = reader.ReadLine();
          listView1.Items.Add("");
          readline = kugiri.Split(',');

          for (int i = 0; i <= this.listBox1.Items.Count - 1; i++)
          {
            listView1.Items[i].SubItems.Add(readline[0].ToString());
          }
        }
    }

このようにすると順に読み込むことはできますが読み込みに時間がかかる、またなぜか偶数列しか読み込まないということが起きてしまいました。

これはどのようにすればいいんでしょうか?ヒントだけでもお願いします。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-27 13:42
引用:

Syouさんの書き込み (2006-02-27 13:30) より:

このようにすると順に読み込むことはできますが読み込みに時間がかかる、
またなぜか偶数列しか読み込まないということが起きてしまいました。


偶数列しか読み込まないのは、ReadLine メソッドでシーク位置が進むからです。
本来は string の変数に取るべきでしょう。

引用:

これはどのようにすればいいんでしょうか?ヒントだけでもお願いします。


System.Collections.Specialized.StringCollection クラスを使ってすべて格納した後に、
加工しつつ、ListView の Items に Add していけば良いでしょう。
カンマで区切る処理自体は必要ないだろうと思います。
もともと区切られているならば、分割する処理は必要でしょうけど。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2006-02-27 13:45
そりゃ一回のループで二回 ReadLine したら偶数行だけにもなるでしょう。

ListViewItemCollection.Add には、引数として String の他にも ListViewItem を渡すオーバーロードもあります。
まず ListViewItem を作り、そこにサブアイテムを追加して、万端整ってから最後に ListView.Items に追加するようにすればいいでしょう。

あと、ListView.BeginUpdate/EndUpdateを使用するとその間描画しないことでパフォーマンスがあがります。
//ただし当然ながらユーザからは処理が終わるまで追加状況が見えなくなりますが。


// 色々かぶったけど送信。
Syou
会議室デビュー日: 2006/02/03
投稿数: 13
投稿日時: 2006-02-27 22:43
引用:

偶数列しか読み込まないのは、ReadLine メソッドでシーク位置が進むからです。
本来は string の変数に取るべきでしょう。



引用:

そりゃ一回のループで二回 ReadLine したら偶数行だけにもなるでしょう。


なるほど・・よく読んでみたらそうでした。すいません・・

引用:

System.Collections.Specialized.StringCollection クラスを使ってすべて格納した後に、
加工しつつ、ListView の Items に Add していけば良いでしょう。
カンマで区切る処理自体は必要ないだろうと思います。
もともと区切られているならば、分割する処理は必要でしょうけど。


型System.Collections.Specialized.StringCollection から型string[]への変換はわかるのですがread.ReadLineは型Stringであるため途中で
型 'string' を型 'System.Collections.Specialized.StringCollection' に暗黙的に変換できません。
とのエラーがでます。

以下がソースです。

StreamReader reader = new StreamReader(stm, System.Text.Encoding.GetEncoding("Shift_JIS"));

System.Collections.Specialized.StringCollection kakunou = new System.Collections.Specialized.StringCollection();

while (reader.Peek() > -1)
{
  kakunou = reader.ReadLine();
}

string[] stringArray = new string[kakunou.Count];
kakunou.CopyTo(stringArray, 0);

引用:

ListViewItemCollection.Add には、引数として String の他にも ListViewItem を渡すオーバーロードもあります。
まず ListViewItem を作り、そこにサブアイテムを追加して、万端整ってから最後に ListView.Items に追加するようにすればいいでしょう。


ListViewItemはよくわからなかったのでMSDNで調べてみたのですが
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.listviewitem.aspx

// Create three items and three sets of subitems for each item.
ListViewItem item1 = new ListViewItem("item1",0);
// Place a check mark next to the item.
item1.Checked = true;
item1.SubItems.Add("1");
item1.SubItems.Add("2");
item1.SubItems.Add("3");
(item2,3は数字が違うのみで同一)
//Add the items to the ListView.
listView1.Items.AddRange(new ListViewItem[]{item1,item2,item3});

のように加えているようですが、これだと毎回listviewitemを作り、reader.ReadLineではすることはできません。この場合どうすればいいのでしょうか?

ぜんぜん知識がなくて申し訳ありません。
引用:

あと、ListView.BeginUpdate/EndUpdateを使用するとその間描画しないことでパフォーマンスがあがります。
//ただし当然ながらユーザからは処理が終わるまで追加状況が見えなくなりますが。


なるほど・・・これを使うと読み込むときの動作が一度に行われるので処理がはやくなりますね。ありがとうございます。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-28 01:27
引用:

Syouさんの書き込み (2006-02-27 22:43) より:

型 'string' を型 'System.Collections.Specialized.StringCollection' に暗黙的に変換できません。
とのエラーがでます。

以下がソースです。

kakunou = reader.ReadLine();


型を意識してみれば自明だと思います。
コレクション == String はかなり無茶です。

ListView の追加と同じ要領なわけですが、Items.Add メソッドを使用します。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Syou
会議室デビュー日: 2006/02/03
投稿数: 13
投稿日時: 2006-02-28 18:25
引用:

型を意識してみれば自明だと思います。
コレクション == String はかなり無茶です。

ListView の追加と同じ要領なわけですが、Items.Add メソッドを使用します。


ぜんぜん気づきませんでした・・・
こんな簡単な質問まで答えてもらってすいません。
Addを基に作ったところ、以下のようなコードでコンパイル/読み込み共に出来ました。ありがとうございます。

コード:
System.Collections.Specialized.StringCollection kakunou = new System.Collections.Specialized.StringCollection();

while (reader.Peek() > -1)
    {
        kakunou.Add(reader.ReadLine());
    }

listView1.Update();

for (int i = 0; i <= kakunou.Count - 1; i++)
   {
        string wakeru;
        wakeru = kakunou[i];

        string[] wakeru2;
        wakeru2 = wakeru.Split(',');

        ListViewItem list1 = new ListViewItem();
        list1.SubItems.Add(wakeru2[0].ToString());
        listView1.Items.AddRange(new ListViewItem[] { list1 });

   }

listView1.EndUpdate();

1

スキルアップ/キャリアアップ(JOB@IT)