

現在、.NET Framework 4.5を使用し、Windowsフォームアプリケーションを作っています。  
指定したテキストファイルを読み込み、行ごとにリストボックスに表示し、その表示された項目を選択（複数選択も可）した後にボタンを押すと、選択していた項目の部分をリストボックスに表示していたテキストファイルから削除するという処理を書いています。  

テキストファイルから直接指定した部分を削除する様な機能は実装されていないと思うので、一度テキストファイルを読み込み、読み込んだデータからリストボックスで指定していた項目を除いたデータを別のファイルに出力し、その出力されたファイルを最初のテキストファイルに上書きする形で実装しようと思いました。  

まず、テキストファイルを読み込み、そのデータをそのまま別のファイルに出力してもとのファイルに上書きすることはできました。  
しかし、リストボックスで選択していた項目を覗いて出力する方法がわからないままです。

以下が書いたコードの一部になります。  

[code]

    StreamReader cReader = (new StreamReader(@"C:\", Encoding.GetEncoding("shift_jis")));
    string stResult = string.Empty;
    string tempFile = @"C:/temp.file"
    string removeTxt = listBox2.SelectedItems.ToString();
    while (cReader.Peek() >= 0)
    {
         string stBuffer = cReader.ReadLine();
         StreamWriter writer = new StreamWriter(tempFile, false, Encoding.GetEncoding("shift-jis"));
         writer.WriteLine(stBuffer);
         writer.Close();
         stResult += stBuffer + Environment.NewLine;<br>
    }
    cReader.Close();
    File.Delete(tempFile);
    
[/code]

上記のコードが、リストボックスで選択している箇所を削除する処理を除いた一連のコードです。  

[code]

    if(cReader.ReadLine() != listBox2.SelectedItems.ToString())
    
[/code]

を使い、選択した項目と一致しなかった時にtempFileに書き込んでいこうとしましたが、うまくいきませんでした。  

何かいい方法がお有りでしたら、ご教授お願いします。

※上記のコードは複数選択された項目ではなく単数選択の項目をテキストファイルから除く処理ですが、複数選択の処理は今回の質問が解決した後に取り組もうと思っています。

.NETのバージョンは4.5です


CC BY-SA 3.0
2014-12-29T08:26:24.890
2777
2014-12-29T12:26:50.213
2014-12-29T10:12:13.427
5798
5798
question
c#
テキストファイルの指定した部分を削除する方法


Formsと仮定しますが、SelectedItemsはSelectedObjectCollection型なのでToStringしても文字列にはなりません。
SelectedItems[0]またはSelectedItemでアクセスする必要があると思われます。


CC BY-SA 3.0
2014-12-29T08:41:42.790
2778
2014-12-29T08:41:42.790
5750
2777
answer


フォームと仮定した上で、listBox1という名前のListBoxコントロールが配置されているとします。  
何らかのボタンのクリックイベントで保存処理を行うものとします。

[code]

    private void button1_Click( object sender1 , EventArgs e1 ) {
        var buf = new StringBuilder();
        for( int i = 0; i < this.listBox1.Items.Count ; i++ ) {
            if( this.listBox1.SelectedIndices.Contains( i ) )
                continue;
            buf.AppendLine( this.listBox1.Items[i] as string );
        }
        File.WriteAllText( @"c:\test.txt" , buf.ToString() );
    }
    
[/code]

なお、リストボックスの項目の型は、stringとします。異なる型を使用する場合、  
下記コードの this.listBox1.Items[i] as string は、nullを返します。  
独自の型を実装する場合、ToStringメソッドをオーバーライドし、 this.listBox1.Items[i].ToStirng()を呼ぶようにします。


CC BY-SA 3.0
2014-12-29T08:47:52.983
2780
2014-12-29T08:47:52.983
2207
2777
answer


ListBoxのSelectedItemsは、単一の選択項目ではなく選択されている全てのアイテムにアクセスするためのコレクション（配列のようなもの）です。

[**MSDN**](http://msdn.microsoft.com/ja-
jp/library/system.windows.forms.listbox.selecteditems%28v=vs.110%29.aspx)では

> ListBox 内で現在選択されている項目を格納するコレクションを取得します。

と説明されています。

ToStringすると
`System.Windows.Forms.ListBox+SelectedObjectCollection`という文字列が返ります。  
（これはSelectedItemsの型を文字で表現したものです。文字として表現できないクラスはこういった値を返します。）

実際に選択されている内容にアクセスするには、SelectedItemsの要素を取り出す必要があります。

質問に提示されたif文をアイテムが選択されているときに最初のアイテムと比較するif文に書き換えると以下の様になります。

[code]

     if(listBox2.SelectedItems.Count > 0 ){ // 少なくとも１つは選択されている
         if(cReader.ReadLine() != (string)listBox2.SelectedItems[0]) // 一つ目に選択されているものと比較
    
[/code]

* * *

ListBoxにもあらかじめ読み込んだテキストファイルの内容があるので、これを信頼してよければ（そのあとファイルが書き換えられていないと言えるなら）、その内容を出力してしまうという手があります。
これはすでに PITAさんのやり方で可能ですが、SelectedIndices以外を使った判断方法を載せておきます。

ListBoxにはGetSelected(int) というメソッドがあり、これを使うと指定されたインデックスのアイテムが選択されているかが取得できます。

これを用いてアイテムが選択されているか判断しながらループ処理することができます。

[code]

    for (var i = 0; i < listBox2.Items.Count; i++){
        if (listBox2.GetSelected(i)){
            // listBox2.Items[i] は選択されている
        }
        else{
            // listBox2.Items[i] は選択されていない
        }
    }
    
[/code]


CC BY-SA 3.0
2014-12-29T12:03:53.040
2794
2014-12-29T12:26:50.213
2014-12-29T12:26:50.213
728
728
2777
answer