【问题标题】:Adding to columns based on length根据长度添加到列
【发布时间】:2013-09-10 04:48:01
【问题描述】:

我有一个包含两列的 ListView,Boxes 和 Files。我将项目添加到字符串列表中,然后使用该字符串列表填充 ListView。我想让所有 8 个字符长的项目进入 Boxes 列,所有 9 个字符的项目进入 Files 列。到目前为止,我已经尝试使用 for 循环进行迭代并使用 if else 语句来添加项目,但我似乎做错了什么。这是我当前的代码:

public void PopulateItemsList()
    {
        BoxAndFileList.Items.Clear();
        ScanIdBox.Text = string.Empty;
        for (int i = 0; i < BoxNumberRepository._boxAndFileList.Count; i++)
        {
            var item = BoxNumberRepository._boxAndFileList.Item[i];
            if (item.Length == 8)
            {
                BoxAndFileList.Items.Insert(0, item);
            }
            else
            {
                BoxAndFileList.Items.Insert(1, item);
            }
        }
    }

我正在遍历我的列表 (_boxAndFileList) 并尝试利用 Insert() 将项目插入到列的特定索引中(Boxes 为 0,Files 为 1)。我可以清楚地看到 Item 是字符串列表的合法属性,但 VS 一直说该列表不包含它的定义。我该怎么做呢?而且,我还没有收到外界对这种做事方式的反馈,所以如果有更好的方法,请告诉我。

编辑:BoxNumberRepository 是一个更新名为 _boxAndFileList 的列表的类。代码如下:

public class BoxNumberRepository : Scan_Form
    {
        public static List<string> _boxAndFileList = new List<string>();

        public void AddItem(string item)
        {
            _boxAndFileList.Add(item);
        }

        public void Delete(string item)
        {
            _boxAndFileList.Remove(item);
        }

        public IEnumerable<string> GetAllItems()
        {
            return _boxAndFileList;
        }
    }

感谢 Alessandro D'Andria 的建议。那是正确的。但是,所有项目仍然只是添加到第一列,即使它们是 9 个字符。如何将 9 个字符项添加到第二列?

【问题讨论】:

  • 您使用的是 WinForms 还是 WPF?
  • 你说你想把 2 种项目放在单独的列中,但是行呢?在每个循环中,您只能在列中插入一项,但列表视图中的一行有 2 列?实际上,您的代码将每个项目插入到单独的行(而不是列)上。
  • 如果 _boxAndFileListList&lt;T&gt; 则没有属性 Items 只是 [i]。
  • 请定义BoxNumberRepository_boxAndFileList

标签: c# winforms listview


【解决方案1】:

您遇到的问题是您必须同时将boxfile 添加到list item

编辑:将笛卡尔积更改为左外连接。

编辑:添加 cmets 并修复语法错误

private List<string> _boxAndFileList = new List<string> { "12345678", "123456789", "1234", "123456778" };
public void PopulateItemsList()
{
    //clear the list
    BoxAndFileList.Items.Clear();
    //add the labels to the top of the listbox
    BoxAndFileList.Columns.Add("Boxes");
    BoxAndFileList.Columns.Add("Files");
    //set the view of the list to a details view (important if you try to display images)
    BoxAndFileList.View = View.Details;
    //clear scan id box
    ScanIdBox.Text = string.Empty;

    //get all the items whos length are 8 as well as a unique id (index)
    var boxes = _boxAndFileList.Where(b => b.Length == 8).Select((b, index) => new { index, b }).ToList();
    //get all the items whos length are NOT 8 as well as a unique id (index)
    var files = _boxAndFileList.Where(f => f.Length != 8).Select((f, index) => new { index, f }).ToList();

    //join them together on their unique ids so that you get info on both sides.
    var interim = (from f in files
                   join b in boxes on f.index equals b.index into bf
                   from x in bf.DefaultIfEmpty()
                   select new { box = (x == null ? String.Empty : x.b), file = f.f });
    //the real trick here is that you have to add 
    //to the listviewitem of type string[] in order to populate the second, third, or more column.
    //I'm just doing this in linq, but var x = new ListViewItem(new[]{"myBox", "myFile"}) would work the same
    var fileboxes = interim.Select(x => new ListViewItem(new []{ x.box, x.file})).ToArray();
    //add the array to the listbox
    BoxAndFileList.Items.AddRange(fileboxes);
    //refresh the listbox
    BoxAndFileList.Refresh();
}

【讨论】:

  • 我不得不承认,这是一段相当复杂的代码,我很难理解。到目前为止,VS 抱怨“字符串”不包含“索引”的定义。看起来没有任何其他属性可以为我提供字符串索引,而不会弹出另一个关于联合子句中的类型不正确的错误。
  • 你是对的!该死的..这是在以前的编辑中。该索引位于选择的覆盖范围内。让我现在解决这个问题
  • ok.. 修复了错误的编辑并添加了 cmets。希望这将澄清整个问题。不要让linq 混淆您。您真正的问题只是使用ListViewItemstring[] 重载,并且您需要将框和文件一起添加到ListBoxItem 而不是一次一个。
  • 查看stackoverflow.com/questions/18707419/…。我问这个问题是为了解决您遇到的左右问题。答案是一个很好的答案,但它可能会挑战你,因为它使用了一种扩展方法。 :D 祝你好运!
  • 挑战,我不介意。我只是希望,如果我对上述挑战有任何疑问,有人会以与您在这篇文章中类似的方式回答我:彻底而耐心。
【解决方案2】:

您的 _boxAndFileList 是 List&lt;string&gt;,因此您应该将项目声明为 string 类型而不是 var 类型:

string item = BoxNumberRepository._boxAndFileList.Item[i];

你所有的代码应该是这样的:

public void PopulateItemsList()
{
    BoxAndFileList.Items.Clear();
    ScanIdBox.Text = string.Empty;
    for (int i = 0; i < BoxNumberRepository._boxAndFileList.Count; i++)
    {
        string item = BoxNumberRepository._boxAndFileList.Item[i];
        if (item.Length == 8)
        {
            BoxAndFileList.Items.Insert(0, item);
        }
        else
        {
            BoxAndFileList.Items.Insert(1, item);
        }
    }
}

【讨论】:

  • 不,OP 甚至似乎都不知道他的代码是做什么的。他希望每个项目位于单独的列上,但此代码将每个项目插入到单独的行上。他可能已经睡着了。所以让我们等他给出更多的澄清。
  • 不确定您是否有意这样做,但这听起来很屈尊。我是一个菜鸟,并且仍然在学习过程中。我知道我想让我的代码做什么,但不确定如何让我的代码去做。我知道这些列有一个索引号,所以我尝试使用它们的索引号推送到这些列。这是对还是错,我不确定。这就是为什么我在这里询问希望知道的人。
  • 不要让@KingKing 接触到你,他是一位出色的开发人员,并且会照原样告诉它,但有时机智过少。 ;)
猜你喜欢
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
相关资源
最近更新 更多