【问题标题】:Problem in databinding Array data to DataGridView in c#c#中将数组数据绑定到DataGridView的问题
【发布时间】:2022-06-11 06:27:36
【问题描述】:

我一直在 C# Winforms 中将短数据绑定到 DataGridView。但是,我需要将大小为 75 的长字符串数组绑定到 DataGridView。我的数据列表类由 6 个单独的变量组成,其中包含 get 和 set 以及我定义了 get 和 set 属性的字符串数组。显示单个变量,但字符串数组未显示在 DataGridView 中。在调试中,我检查了 DataGridView 的数据源,似乎没问题。如何在 gridview 中显示绑定数组。

下面是我用来填充名为 Logview 的 DataGridView 的源代码

    public void populateLogData(string path)
    {
        StreamReader sr = null;
        BindingList<LogList> bindLogList;
        BindingSource bLogsource = new BindingSource();
        List<LogList> loglist = new List<LogList>();
        
        try
        {
            Logview.DataSource = null;
            Logview.Rows.Clear();
            Logview.Columns.Clear();
            Logview.AutoGenerateColumns = true;
            
            if (File.Exists(path))
            {
                try
                {                        
                    sr = new StreamReader(path);
                    StringBuilder readline = new StringBuilder(sr.ReadLine());
                    if (readline.ToString() != null && readline.ToString() != "")
                    {
                        readline = new StringBuilder(sr.ReadLine());
                        while (readline.ToString() != null && readline.ToString() != "")
                        {
                            string[] subdata = readline.ToString().Split(',');
                            LogList tloglist = new LogList(subdata[0], subdata[1], subdata[2], subdata[3], subdata[4], subdata[5], max_index);
                            for (int i = 6; i < subdata.Length; i++)
                                tloglist.setPartList(i-6, subdata[i]);                                
                            loglist.Add(new LogList(subdata, subdata.Length));
                            readline = new StringBuilder(sr.ReadLine());
                        }
                    }
                    bindLogList = new BindingList<LogList>(loglist);
                    bLogsource.DataSource = bindLogList;
                    Logview.AutoGenerateColumns = true;
                    Logview.DataSource = bindLogList;
                    
                    Logview.Columns[0].Width = 140;        // project name
                    Logview.Columns[1].Width = 140;        // data/time

                    Logview.Columns[2].Width = 90;
                    Logview.Columns[3].Width = 90;
                    Logview.Columns[4].Width = 90;
                    Logview.Columns[5].Width = 90;

                    // max_index is set from another part of code
                    for(int i = 0; i <= max_index; i++)
                    {
                        int counter = 6 + i;
                        Logview.Columns.Add(headertext[i], headertext[i]);
                        Logview.Columns[counter].Width = 90;
                        Logview.Columns[counter].HeaderText = headertext[i];
                    }
                }
                catch (IOException io)
                {
                    MessageBox.Show("Error: Cannot Open log file.");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    if (sr != null) sr.Close();
                }
            }
            else
            {
                MessageBox.Show("Log file not found \n" + path);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {
            GC.Collect();
        }
    }

下面是LogList类

    class LogList
    {
        const int max_size = 100;
        private string[] holdList;
        public string project { get; set; }
        public string date_time { get; set; }
        public string Qty { get; set; }
        public string Pass { get; set; }
        public string Fail { get; set; }
        public string Result { get; set; }
        public string[] partlist
        {
            get
            {
                return holdList;
            }
            set
            {
                holdList = value;
            }
        }

        public LogList(string project, string date_time, string Qty, string Pass, string Fail, string Result, int partsize)
        {
            this.project = project;
            this.date_time = date_time;
            this.Qty = Qty;
            this.Pass = Pass;
            this.Fail = Fail;
            this.Result = Result;

            partlist = new string[partsize+1];            
        }

        public void setPartList(int size, string getValue)
        {
            partlist[size] = getValue;
        }
    }

显示项目、日期/时间、数量、通过、失败、结果。但是没有显示partlist数组。

【问题讨论】:

  • 您到底希望看到什么? DataGridView 无法提供有用的数组表示。最好是调用ToString,在这种情况下你会得到“System.Array”之类的。
  • 查看LogList 类……partlist 是一个string[] 数组。当您设置网格DataSource 时,它将绑定所有公开公开的原始属性类型,如bool、string、int…等。但是,它不会绑定类的“属性”其他类或集合。在这种情况下,partlist 是一个“集合”,网格不知道如何将“多个”值添加到单个单元格中。您将不得不展平 partlist 项目或以主从方式使用两个网格。
  • @JohnG 我猜这就是原因。 “扁平化部分列表”是否意味着无论数组有多大,我都必须将所有项目单独分配到单独的公共属性中?
  • ““扁平化partlist”是否意味着无论数组有多大,我都必须将所有项目单独分配到单独的公共属性中?” ...从技术上讲,是的...但是... 不... 因为数组可以是任意大小,所以您必须检查每个 partlist 大小以查看哪个列表最长,然后才能在网格中创建适当数量的列。此外,这可能会使许多单元格“空白”并且永远不会被使用。因此,以这种方式展平数据并不是一个好主意。
  • 然而,解决这个问题的一种“简单”方法……是在 LogList 类中创建另一个属性。类似“AllPartsString”的东西。在get 属性中,您可以创建一个新的StringBuilder,并通过一个foreach 循环遍历所有partlist 项。创建一个包含所有零件值的“单个”字符串。然后在数据绑定到网格时会创建此列。授予“一个”(1) 单元格将包含该单个 LogList 项目的所有部分。

标签: c# visual-studio winforms data-binding datagridview


【解决方案1】:

您的数据列表类包含 6 个单独的变量,分别是 get 和 set,以及一个字符串数组。您的问题是关于显示变量但未显示字符串数组。

以下是显示字符串数组的方法(类似于 JohnG 的出色建议)。我在这里所做的是采用DataGridView 并在不更改任何设置的情况下放入我的主表单(Dock 除外)。给定默认设置,LogList 类(此处显示为 1 个变量和 1 个字符串数组的最小可重现示例)是使用名为 PartList 的公共字符串属性定义的,并具有以下基本实现:

class LogList
{
    public LogList(string product, string[] partList)
    {
        Product = product;
        _partList = partList;
    }
    public string Product { get; set; }

    private string[] _partList;
    public string PartList => string.Join(",", _partList);
}

要使用Product 和PartList 属性自动配置DataGridView,下面是一个设置DataSource 并添加前三个项目作为测试的示例方法:

// Set data source property once. Clear it, Add to it, but no reason to nullify it.
BindingList<LogList> DataSource { get; } = new BindingList<LogList>();

private void InitDataGridView()
{
    dataGridView1.DataSource = DataSource;
    // Auto config columns by adding at least one Record.
    DataSource.Add(
        new LogList(
            product: "LMG450",
            // Four parts
            partList: new string[]
            {
                "PCT2000",
                "WCT100",
                "ZEL-0812LN",
                "EN61000-3-3/-11",
            }
        ));
    DataSource.Add(
        new LogList(
            product: "LMG600N", 
            // Three parts
            partList: new string[] 
            { 
                "LTC2280",
                "BMS6815",
                "ZEL-0812LN",
            } 
        ));
    DataSource.Add(
        new LogList(
            product: "Long Array",
            // 75 parts
            partList: Enumerable.Range(1, 75).Select(x => $"{ x }").ToArray()
        ));

    // Use string indexer to access columns for formatting purposes.
    dataGridView1
        .Columns[nameof(LogList.Product)]
        .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

    dataGridView1
        .Columns[nameof(LogList.PartList)]
        .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

}

运行此代码后,DGV 如下所示:

将鼠标悬停在项目上,可以查看所有 75 个项目。

我希望这里有一些想法可以提供一些想法来实现您想要的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 2012-07-10
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多