Записать первую и вторую строки столбца в listview внутри каждой строки текстового файла

#c# #.net #winforms #listview #text-files

#c# #.net #винформы #просмотр списка #текстовые файлы #winforms #listview

Вопрос:

Я использую WinForms . В моей форме у меня есть listview и кнопка. Когда я нажимаю на кнопку, программа записывает все элементы в listview в текстовый файл. Проблема в том, что я хочу, чтобы первый и второй столбцы были в одной строке.

Вот мой код, который я использую для записи в текстовый файл:

             using (StreamWriter sw = File.CreateText(DirectoryPath))
            {
                foreach (ListViewItem item in listView1.Items)
                {
                    sw.WriteLine(item.Text);
                    for (int i = 1; i < item.SubItems.Count; i  )
                    {
                        sw.WriteLine(item.SubItems[i].Text);
                    }
                }
             }
  

Мой ListView

Мой просмотр списка

Проблема с выводом текстового файла

Проблемный текстовый файл

Как я хочу, чтобы текстовый файл отображался

Цель

Комментарии:

1. Вы могли бы просто использовать sw. Write(Item.Text) вместо WriteLine, поэтому строка не завершается после записи текста элемента.

Ответ №1:

Как насчет просто

        using (StreamWriter sw = File.CreateText(DirectoryPath))
        {
            foreach (ListViewItem item in listView1.Items)
            {
                sw.Write(item.Text   ": ");
                for (int i = 1; i < item.SubItems.Count; i  )
                {
                    sw.WriteLine(item.SubItems[i].Text);
                }
            }
         }
  

Ответ №2:

Кажется, что ваша первая ячейка «FirstPage» является родительской, а все остальные элементы являются подпунктами. Предполагая, что у вас есть только два столбца ниже, ответ будет работать.

 using (StreamWriter sw = File.CreateText(DirectoryPath))
        {
            foreach (ListViewItem item in listView1.Items)
            {

                sw.Write(string.Format("{0} :",item.Text));
                for (int i = 1; i < item.SubItems.Count; i  )
                {
                    if (i % 2 == 0)
                    {
                        sw.Write(string.Format("{0} :",item.SubItems[i].Text));

                    }
                    else
                    {
                        sw.WriteLine(item.SubItems[i].Text);
                    }
                }
            }
        }
  
  • Альтернативный вариант; добавьте каждую новую строку как новый элемент в представление списка

         string[] row = { "FirstPage", "$1.00" };
        string[] row2 = { "SecondPage", "$1.00" };
    
        var listViewItem = new ListViewItem(row);
        listView1.Items.Add(listViewItem);
        var listViewItem2 = new ListViewItem(row2);
        listView1.Items.Add(listViewItem2);
      

    и так далее. Вы можете выполнить итерацию через цикл foreach для этого добавления, а затем использовать приведенный ниже код, который является гибким.

        using (StreamWriter sw = File.CreateText(DirectoryPath))
        {
            foreach (ListViewItem item in listView1.Items)
            {
    
                sw.Write(string.Format("{0} :",item.Text));
                for (int i = 1; i < item.SubItems.Count; i  )
                {
                    sw.WriteLine(item.SubItems[i].Text);
                }
            }
        }
      

Ответ №3:

Вы можете сделать это более элегантным способом:

 var str = listView1.Items.Cast<ListViewItem>()
                   .Select(x => x.SubItems.Cast<ListViewItem.ListViewSubItem>())
                   .Select(x => string.Join(":", x.Select(s => s.Text)));
System.IO.File.WriteAllLines(@"d:file.txt", str);
  

Примечание: Если вы хотите ограничить столбцы, например, сохранить только первые два столбца, вы можете выбрать подпункты во второй строке таким образом: x.SubItems.Cast<ListViewItem.ListViewSubItem>().Take(2)

Комментарии:

1. Мне нравится LINQ, но бывают случаи, подобные этому, когда главное, что он делает, — это скрывает, что делает код.

2. @AgapwIesu Код работает следующим образом: Cast<T>() преобразует перечислимую коллекцию в IEnumerable<T> , чтобы мы могли использовать для нее методы linq. Таким образом, мы получаем список элементов в первой строке. Затем во второй строке мы выбрали все подпункты элемента, так что результатом является список, каждый элемент которого содержит список подпунктов элемента. Затем в третьей строке мы выделили текст из всех подпунктов и, используя string.Join , объединили эти подпункты, используя «:» в качестве разделителя.

3. @AgapwIesu Практика совершенствует. Когда вы будете использовать его достаточно, вы будете читать строки так же просто, как вы читаете цикл for, и вы научитесь разбирать его, и вы увидите, что это одно из лучших решений, которое вы можете использовать для такого случая.

Ответ №4:

Вы должны выполнить итерацию элементов представления списка, объединить каждый из подпунктов друг с другом, а затем добавить объединенную строку в текстовый файл в конце… Я адаптировал ваш код:

 using (StreamWriter sw = File.CreateText(DirectoryPath))
{
    foreach (ListViewItem item in listView1.Items)
    {

        string strText = "";

        //I'm not sure why you start at 1 and not 0, anyway:
        for (int i = 1; i < item.SubItems.Count; i  )
        {
            strText = " "   item.SubItems[i].Text;
        }

        sw.WriteLine(strText);
    }
 }
  

Комментарии:

1. Я думаю, что строка в вашем коде нуждается в исправлении strText = » » sw.WriteLine(item. Подпункты[i].Текст); на самом деле должно быть strText = » » item. Подпункты[i].Текст;