Как в цикле поменять значения в колонке ListView?

137
16 февраля 2021, 04:20

Есть listview с двумя колонками. Имя второй колонки Stats. Как пройтись в цикле по всем строкам listview и поменять значения во второй колонке на какой нибудь текст?

Answer 1

По сути нужно найти у каждого элемента Items вложенный элемент SubItems, соответствующий заданной колонке. Если точно известно, что это вторая колонка (номер 1) и что что такой подэлемент всегда есть, то подойдет такой код:

foreach (ListViewItem item in listView.Items)
{
    item.SubItems[1].Text = "Some text";
}

Если есть вероятность того что не у всех элементов есть подэлемент, то можно добавить нужное число элементов:

int targetColumnNumber = 1;
foreach (ListViewItem item in listView.Items)
{
    //если не хватает SubItems
    if (item.SubItems.Count <= targetColumnNumber)
    {
        //то добавляем сколько нужно
        for (int i = 0; i < targetColumnNumber - item.SubItems.Count + 1; i++)
        {
            item.SubItems.Add("");
        }
    }
    item.SubItems[targetColumnNumber].Text = "Some text";
}

Еще можно учесть, что положение столбцов будет меняться и не прописывать индекс колонки, а искать ее по имени:

//выбросит исключение если колонки «Stats» нет
int targetColumnNumber = listView.Columns.Cast<ColumnHeader>().First(c => c.Text == "Stats").Index;

Исполняемый пример:

using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        var listView = new ListView { Dock = DockStyle.Top, View = View.Details };
        listView.Columns.Add("Name");
        listView.Columns.Add("Stats");
        listView.Columns.Add("Value");
        var items = new[] { "One", "Two", "Three" };
        var subItems = new[]
        {
            new string[]{ "", "1"},
            new string[]{ "", "2"},
            new string[]{},
        };
        for (int i = 0; i < items.Length; i++)
        {
            var item = listView.Items.Add(items[i]);
            item.SubItems.AddRange(subItems[i]);
        }
        var button = new Button { AutoSize = true, Dock = DockStyle.Bottom, Text = "Set Stats" };
        button.Click += (s, e) =>
        {
            //выбросит исключение если колонки «Stats» нет
            int targetColumnNumber = listView.Columns.Cast<ColumnHeader>().First(c => c.Text == "Stats").Index;
            foreach (ListViewItem item in listView.Items)
            {
                //если не хватает SubItems
                if (item.SubItems.Count <= targetColumnNumber)
                {
                    //то добавляем сколько нужно
                    for (int i = 0; i < targetColumnNumber - item.SubItems.Count + 1; i++)
                    {
                        item.SubItems.Add("");
                    }
                }
                item.SubItems[targetColumnNumber].Text = "Some text";
            }
        };
        var form = new Form{ ClientSize = new Size(300, 200) };
        form.Controls.Add(listView);
        form.Controls.Add(button);
        Application.Run(form);
    }
}

Результат:

READ ALSO
Существуют ли какие-то затраты на преобразование объектов?

Существуют ли какие-то затраты на преобразование объектов?

С преобразованием значимого типа в объект и обратно все понятно — там появляются допоперации на упаковку/распаковку

125
Изменить стиль выделения заголовка столбца DataGridView

Изменить стиль выделения заголовка столбца DataGridView

На скриншотах: первая строка ListView, вторая строка DataGridView

107
Как вывести в label.Text &ldquo;string&rdquo; значение (Windows Form Application)

Как вывести в label.Text “string” значение (Windows Form Application)

Всем привет, подскажите как вывести стринговое значение (string) в labelText (C#, Visual Studio 2017, Windows Form Application);

120