带有填充组合框的数据网格视图并从文本文件中读取

datagridview with populated comboboxs and read from text file

我搜索了这个网站并 Google 寻找答案,并尝试根据我的具体情况调整各种答案,但没有成功。我发现了很多 "fill combobox with values from a text file or from DB" 但这不是我需要的。这是在 C# 中使用 Visual Studio 2012。

我有一个 datagridview,它有 4 列和 17 行。第一行只是列名。 header 下的第一列是每行的#s 1-16。该字段的其余部分是具有指定值的组合框,所有这些值都需要保留。这一切都是通过代码而不是通过属性完成的。因此,如果我只是转到 datagridview,它会正确显示,我可以更改值并保存它。当此人打开文件并显示时,我也需要它,他们可以单击组合框并更改该值。

我已经做到了,所以我可以从特定格式的文本文件中读取,但 datagridview 中的结果是带有值的 4x17 文本框。位置和值都是正确的,但我需要将这些值放在预建的组合框中。文本文件的值将始终是预建组合框中的值之一。

这是一个很好的网站,可以用来寻找答案并作为解决我的问题的起点,所以我希望我能在这方面得到一些帮助。我尽量说得具体一些,希望大家能看懂。

这是我打开的对话框和读取的文本文件。我在想我需要创建我的组合框或 link 将它们创建到我的预建组合框,但这就是我感到困惑的地方。

if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            System.IO.StreamReader file = new System.IO.StreamReader(openFileDialog1.FileName);
            string[] columnnames = file.ReadLine().Split(',');
            DataTable dt = new DataTable();

            foreach (string c in columnnames)
            {
                dt.Columns.Add(c);                    
            }
            string newline;
            while ((newline = file.ReadLine()) != null)
            {
                DataRow dr = dt.NewRow();
                string[] values = newline.Split(',');
                for (int i = 0; i < values.Length; i++)
                {
                    dr[i] = values[i];
                }
                dt.Rows.Add(dr);
            }
            dataGridView1.DataSource = dt;
            file.Close();

这是我预建的组合框代码。组合框中的值需要保留。我将其构建为构造函数,因为我在加载表单时拥有它,但我更改了它并在需要时调用它。

private void filldata()
    {
        //text column
        dataGridView1.ColumnCount = 1;
        dataGridView1.Columns[0].Name = "Channel";
        dataGridView1.Columns["Channel"].ReadOnly = true;
        dataGridView1.Rows.Add();
        dataGridView1[0, 0].Value = "1";
        dataGridView1.Rows.Add();
        dataGridView1[0, 1].Value = "2";
        dataGridView1.Rows.Add();
        dataGridView1[0, 2].Value = "3";
        dataGridView1.Rows.Add();
        dataGridView1[0, 3].Value = "4";
        dataGridView1.Rows.Add();
        dataGridView1[0, 4].Value = "5";
        dataGridView1.Rows.Add();
        dataGridView1[0, 5].Value = "6";
        dataGridView1.Rows.Add();
        dataGridView1[0, 6].Value = "7";
        dataGridView1.Rows.Add();
        dataGridView1[0, 7].Value = "8";
        dataGridView1.Rows.Add();
        dataGridView1[0, 8].Value = "9";
        dataGridView1.Rows.Add();
        dataGridView1[0, 9].Value = "10";
        dataGridView1.Rows.Add();
        dataGridView1[0, 10].Value = "11";
        dataGridView1.Rows.Add();
        dataGridView1[0, 11].Value = "12";
        dataGridView1.Rows.Add();
        dataGridView1[0, 12].Value = "13";
        dataGridView1.Rows.Add();
        dataGridView1[0, 13].Value = "14";
        dataGridView1.Rows.Add();
        dataGridView1[0, 14].Value = "15";
        dataGridView1.Rows.Add();
        dataGridView1[0, 15].Value = "16";

        //combo box
        DataGridViewComboBoxColumn freqRXTX = new DataGridViewComboBoxColumn();
        freqRXTX.HeaderText = "Frequency (MHz)";
        String[] RXTX = { "", "467.0", "471.9", "474.4", "477.0", "479.7" };
        freqRXTX.Items.AddRange(RXTX);
        dataGridView1.Columns.Add(freqRXTX);

        DataGridViewComboBoxColumn CTCSSfreq = new DataGridViewComboBoxColumn();
        CTCSSfreq.HeaderText = "CTCSS (Hz)";
        String[] CTCSS = { "none", "67.0", "71.9", "74.4", "77.0", "79.7", "82.5", "85.4", "88.5", "91.5", "94.8", "97.4", "100.0", "103.5", "107.2", "110.9", "114.8", "118.8", "123.0", 
        "127.3", "131.8", "136.5", "141.3", "146.2", "151.4", "118.8", "123.0", "127.3", "131.8", "136.5", "141.3", "146.2", "151.4", "210.7", "218.1", "225.7", "233.6", "241.8", "250.3"};
        CTCSSfreq.Items.AddRange(CTCSS);
        dataGridView1.Columns.Add(CTCSSfreq);

        DataGridViewComboBoxColumn DCSfreq = new DataGridViewComboBoxColumn();
        DCSfreq.HeaderText = "DCS (Hz)";
        String[] DCS = { "none", "23", "25", "26", "31", "32", "43", "47", "51", "54", "65", "71", "72", "73", "74", "114", "115", "116", "125", "131", "132", "134", "143", "152", "155", "156", "162", "165",
        "172", "174", "205", "223", "226", "243", "244", "245", "251", "261", "263", "265", "271", "306", "311", "315", "331", "343", "346", "351", "364", 
        "365", "371", "411", "412", "413", "423", "431", "432", "445", "464", "465", "466", "503", "506", "516", "532", "546", "565", "606", "612", "624",
        "627", "631", "632", "654", "662", "664", "703", "712", "723", "731", "732", "734", "743", "754" };
        DCSfreq.Items.AddRange(DCS);
        dataGridView1.Columns.Add(DCSfreq);

您的代码有一些问题。

手边的问题可能是您没有在 DataGridView 中设置列​​的 DataPropertyName

你可以这样做,在你的第一段代码中,即在设置 table:

for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
    dataGridView1.Columns[i].DataPropertyName = dt.Columns[i].ColumnName;
}

你还需要先调用第二块,因为它会设置DataGridView

在其中您可以像这样简化设置:

//text column
dataGridView1.ColumnCount = 1;
dataGridView1.Columns[0].Name = "Channel";  // !*!
dataGridView1.Columns["Channel"].ReadOnly = true;
dataGridView1.Rows.Add(16);
for (int i = 1; i <= 16; i++)
{
    dataGridView1[0, i].Value = i + "";
}
..

我注意到 (!*!) 您只设置了一个 DataGridView.Column ('Channel') 的 Name 属性。这没关系,但有点混乱;尽量保持你的代码一致,否则你的(或其他人)会在稍后的某个时候开始怀疑它..

请注意,我没有对 DataTable 中的列数进行任何 检查 以使其不小于 DataGridView 中的列数!

另请注意,您可以自由地将 any DataGridView.Columnany DataTable.Column 关联,至少只要他们的数据类型不冲突.. 我只是假设他们的订单适合..

另请注意,值得考虑将 DataTable 声明移到 class 级别,这样您就可以直接从其他代码段访问它。只要它被设置为 DGV 的 DataSource,它就会保留在代码中;仍然可以通过将 dataGridView1.DataSource 转换为 DataTable 来访问它,但它会更简单、更清晰,imo。为此,您必须在代码中保留实例化,只需移动声明即可!

请注意,您通常必须决定 datagridview 的列是在代码中生成还是由数据绑定源生成。对于前一组 dataGridView1.AutoGeneratecolumns = false; !