【问题标题】:How can I read ListView Column Headers and their values?如何读取 ListView 列标题及其值?
【发布时间】:2015-05-16 05:48:05
【问题描述】:

我一直在尝试找到一种方法来从选定的ListView 行中读取数据,并在其受人尊敬的TextBox 中显示每个值以便于编辑。

第一个也是最简单的方法是这样的:

ListViewItem item = listView1.SelectedItems[0];

buyCount_txtBox.Text = item.SubItems[1].Text;
buyPrice_txtBox.Text = item.SubItems[2].Text;
sellPrice_txtBox.Text = item.SubItems[3].Text;

该代码没有任何问题,但我有大约 40 个或更多 TextBoxes 应该显示数据。编码全部 40 个左右会变得非常乏味。

我想出的解决方案是在我的用户控件中获取所有 TextBox 控件,如下所示:

    foreach (Control c in this.Controls)
    {
        foreach (Control childc in c.Controls)
        {
            if (childc is TextBox)
            {
            }
        }
    }

然后我需要循环选定的ListView 行列标题。如果他们的列标题与 TextBox.Tag 匹配,则在他们尊重的 TextBox 中显示列值。

最终的代码如下所示:

    foreach (Control c in this.Controls)
    {
        foreach (Control childc in c.Controls)
        {

          // Needs another loop for the selected ListView Row

            if (childc is TextBox && ColumnHeader == childc.Tag)
            {
               // Display Values
            }
        }
    }

那么我的问题是:如何循环遍历选定的 ListView 行和每个列标题。

【问题讨论】:

    标签: c# winforms listview columnheader


    【解决方案1】:

    循环遍历你的ColumnHeaders 就像这样简单地完成:

    foreach(  ColumnHeader  lvch  in listView1.Columns)
    {
        if (lvch.Text == textBox.Tag) ; // either check on the header text..
        if (lvch.Name == textBox.Tag) ; // or on its Name..
        if (lvch.Tag  == textBox.Tag) ; // or even on its Tag
    }
    

    但是,您循环访问 TextBoxes 的方式并不完全好,即使它有效。我建议您将每个参与的TextBoxes 添加到List<TextBox> 中。是的,这意味着添加 40 个项目,但您可以使用 AddRange 可能是这样的:

    填写列表 myBoxes:

    List<TextBox> myBoxes = new List<TextBox>()
    
    public Form1()
    {
        InitializeComponent();
        //..
        myBoxes.AddRange(new[] {textBox1, textBox2, textBox3});
    }
    

    或者,如果你真的想避免 AddRange 并保持动态,你也可以编写一个微小的递归......:

    private void CollectTBs(Control ctl, List<TextBox> myBoxes)
    {
        if (ctl is TextBox) myBoxes.Add(ctl as TextBox);
        foreach (Control c in ctl.Controls) CollectTBs(c, myBoxes);
    }
    

    现在你的最后一个循环又小又快:

    foreach(  ColumnHeader  lvch  in listView1.Columns)
    {
        foreach (TextBox textBox in myBoxes)
            if (lvch.Tag == textBox.Tag)  // pick you comparison!
                textBox.Text = lvch.Text;
    }
    

    更新:由于您实际上想要 SubItem 值,因此解决方案可能如下所示:

    ListViewItem lvi = listView1.SelectedItems[0];
    foreach (ListViewItem.ListViewSubItem lvsu in  lvi.SubItems)
        foreach (TextBox textBox in myBoxes)
           if (lvsu.Tag == textBox.Tag)  textBox.Text = lvsu.Text;
    

    【讨论】:

    • 哦,我什至没有想到这一点。我不知道为什么我没有看到。哈哈。我的意思是我需要从所选行中获取值,而不是标题。
    • 好吧,无论如何我已经更新了答案;-) 请注意我循环子项的方式:必须限定 ListViewSubItem 类型!
    猜你喜欢
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    相关资源
    最近更新 更多