【问题标题】:ListView blank after populating填充后 ListView 空白
【发布时间】:2018-05-25 07:31:17
【问题描述】:

我有一个Dictionary<string, string> obejct,其数据应该通过TextBox控件中提交的文本实时过滤,然后显示在ListView控件中。

我想出的解决方案是:

  • Dictionary<string, string> 转换为DataTable

  • 使用文本框的TextChanged事件触发过滤器

  • 将过滤后的记录放入DataRow[] 数组,将所述数组作为参数传递给自定义方法以填充ListView 对象

现在,这就是我转换字典的方式:

static DataTable dtDepartments { get; set; }
static Dictionary<string, string> GetDepartments(string _depNum, out bool _isOff) 
 {
     // retrieve the list from a SQL Server DB
 }

public myForm()
{
    InitializeComponent();

    Dictionary<string, string> Departments = new Dictionary<string, string>();
    Departments = GetDepartments(string.Empty, out bool _isOff);

    dtDepartments = new DataTable();
    dtDepartments.TableName = "DEPARTMENTS";
    DataColumn idColumn = dtDepartments.Columns.Add("NUM", typeof(string));
    dtDepartments.Columns.Add("NAME", typeof(string));
    dtDepartments.PrimaryKey = new DataColumn[] { idColumn };

    foreach(KeyValuePair<string,string> kvP in Departments)
    {
        dtDepartments.Rows.Add(new object[] { kvP.Key, kvP.Value });
    }
}

这就是我在事件方法中填充列表的方式

private void txtFilter_TextChanged(object sender, EventArgs e)
{
    string filter = "NAME LIKE '%" + txtFilter.Text + "%'";
    DataRow[] foundRows = dtDepartments.Select(filter);

    if (foundRows.Length > 0)
    {
        lvDepartments.Visible = true;
        ResizeListView(foundRows.Length);
        PopulateListView(foundRows);
    }
}

void ResizeListView(int _rows)
{
    lvDepartments.Height = Math.Min(25 + (20 * _rows), 205);
}

void PopulateListView(DataRow[] _foundRows)
{
    lvDepartments.Items.Clear();
    ListViewItem depNum = new ListViewItem("NUM", 0);
    ListViewItem depName = new ListViewItem("NAME", 0);
    foreach (DataRow row in _foundRows)
    {
        depNum.SubItems.Add(row.Field<string>("NUM"));
        depName.SubItems.Add(row.Field<string>("NAME"));
    }

    lvDepartments.Columns.Add("Number", -2, HorizontalAlignment.Left);
    lvDepartments.Columns.Add("Name", -2, HorizontalAlignment.Left);

    lvDepartments.Items.AddRange(new ListViewItem[] { depNum, depName });
}

DataRow[] 数组已正确填充,ResizeListView(int _rows) 方法在调整列表高度方面发挥作用,ListView 正确显示列标题,但其余只是空白行。

我在 MSDN 上关注了 these instructions,但我真的找不到我缺少的东西。

非常感谢任何建议。

谢谢-

【问题讨论】:

    标签: c# winforms listview datatable


    【解决方案1】:

    看起来您要为每列添加一个 ListViewItem,每行添加一个 SubItem。反之亦然。

    第一列由 ListViewItem Text 属性填充。第二到第 n 列由提供给 SubItems.Add() 的字符串填充。

    以上假设您使用的是详细信息View 模式,这是唯一允许多列的视图。

    void PopulateListView(DataRow[] _foundRows)
    {
        lvDepartments.Items.Clear();
        foreach (var row in _foundRows)
        {
            var item = new ListViewItem { Text = row.Field<String>("NUM") };
            item.SubItems.Add( row.Field<String>("NAM") );
            lvDepartments.Items.Add( item );
        }
    }
    

    或者如果你是 LINQ-y

    void PopulateListView(DataRow[] _foundRows)
    {
        lvDepartments.Items.Clear();
        lvDepartments.Items.AddRange
        (
            _foundRows.Cast<DataRow>().Select
            ( 
                row =>
                {
                    var item = new ListViewItem
                    {
                        Text = row.Field<string>("NUM")
                    };
                    item.SubItems.Add( row.Field<string>("NAME") );
                    return item;
                }
            )
            .ToArray()
        );
    }
    

    【讨论】:

    • 非常感谢...我得到了相反的结果:)