【问题标题】:Problem with format in C# with DataGridView and TextBox使用 DataGridView 和 TextBox 在 C# 中的格式问题
【发布时间】:2020-04-21 18:19:09
【问题描述】:

我在 C# 中遇到了格式问题。 我有一个 DataGridView 和一个 TextBox。在这个datagridview 中,有一列:单价(格式为int)。 我想对单个价格列的每个元素求和并将结果插入此文本框中,但 Visual Studio 给我一个字符串输入格式的问题(“输入字符串的格式不正确”)。 这是我使用的代码:

int TOT = 0;
                for (int i = 0; i < dataGridView3.Rows.Count; i++)
                {
                    TOT = TOT + Convert.ToInt32(dataGridView3.Rows[i].Cells[6].ToString());
                }
                textBoxTot.Text = Convert.ToString(TOT);

你能帮我解决这个严重的错误吗?

更新: 我认为现在的问题是另一个问题。我找不到可以给我查询结果的 MySql.Data.MySqlClient 库的方法。

MySqlCommand command = new MySqlCommand();
            String sumQuery = "SELECT SUM(`prezzo`) FROM `fatturetemp`";
            command.CommandText = sumQuery;
            command.Connection = conn.getConnection();
            command.Parameters.Add("@prezzo", MySqlDbType.Int32).Value = costo;
            conn.openConnection();
            conn.closeConnection();

给我 sumQuery 结果的命令如何。如果我找到这个命令,我可以把查询结果粘贴到文本框中

【问题讨论】:

  • 为什么要先将值转换为字符串?第 7 列中的数据类型是什么?为什么不直接转换为 int (如果是价格,则更可能是十进制)。
  • 顺便说一句,您可能会在新行上遇到该错误。检查该行是否为 IsNewRow。 (dataGridView3.Rows[I].IsNewRow)
  • 因为没有.ToString,给我错误。 7列的数据类型是int。
  • 我已经更新了我的答案。现在的问题是另一个问题。你能帮帮我吗?

标签: c# visual-studio


【解决方案1】:

如果您的 datagridview 显示的是数据表(即您的数据存储在数据表中),您可以将 DataColumn 添加到数据表,其 .Expression 属性设置为字符串 "SUM([Price])",其中 Price 是包含价格信息的数字数据类型列的名称。

现在表格中的每一行都会有价格的总和(一遍又一遍的相同值),所以如果你想将你的文本框数据绑定到这个新列,那么无论哪一行都是总和当前行(因为所有行都具有相同的值)。它还会自动更新,无需您做任何事情!

如果您不使用数据绑定到数据表,我建议您这样做,因为它代表了良好的 MVC 实践,将数据保存在一个事物中(DataTable)并显示在另一个事物中(DataGridView)并保留这些关注分开

它看起来像这样,作为一个简单的例子:

        DataTable dt = new DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("Price", typeof(int));
        dt.Columns.Add("CalculatedTotal", typeof(int)).Expression = "SUM([Price])";
        dt.Rows.Add("Apples", 100);
        dt.Rows.Add("Oranges", 200);

        BindingSource bs = new BindingSource();
        bs.DataSource = dt;

        WhateverDataGridView.DataSource = bs;
        totalTextBox.DataBindings.Add(new Binding("Text", bs, "CalculatedTotal", true));

这里有一个数据模型(数据表),用于保存数据。它有一些我们可以直接设置的东西,以及根据所有表格中的现有价格计算的第三列。如果您在 datagridview 中查看此内容(假设您打开了 autogeneratecolumns),您会看到两行对于 CalculatedTotal 都有 300,但它们的价格有单独的金额。在数据表和 UI 控件之间有一个称为 BindingSource 的设备;您不必拥有一个,但它使某些事情在数据更改时更容易更新控件,并且它保持“当前”的概念 - 基本上无论您在 datagridview 中查看的当前行是什么;这一切都有助于避免向 DGV 询问任何事情——我们只是让用户在 DGV 中键入,它会显示数据表中的数据。我们所有的交易都可以直接与数据表进行 - 如果您编写了一个按钮来循环遍历表并将所有价格翻倍,那么 UI 中的控件将自动反映更改。文本框通过数据绑定连接到CalculatedValue 列;无论当前行是什么,文本框都会显示CalculatedValue。因为CalculatedValue 列在每一行上都有相同的值,并且如果价格发生任何变化,它们总是会更新,所以总文本框将始终显示总和。添加另一个绑定到名称的文本框以了解我的意思;当您在网格周围单击并选择不同的行作为“当前”行时,名称会改变,但总数不会改变。事实上,它实际上以与 Name 相同的方式发生变化,只是因为每一行的实际数值都是相同的,所以文本框的内容看起来就像它们没有改变

【讨论】:

  • 他对数据源只字未提,也不想在新列中显示它,而是在文本框中显示它。如果该列没有数字数据,那么这样的表达式甚至都行不通。
  • 我知道(我说过,不是吗?);应该这样做;我正在修复他的 XY 问题中的 X - 你正在修复 Y
  • :) 是“你”如何做,而不是应该如何做。顺便说一句,你没有,你后来编辑这么说。
  • 是的,我不确定您是否会让许多有经验的开发人员同意直接将装箱为对象的数据推入和推出 DataGridView 是应该做的任何事情。他们中的大多数人会鼓励人们将他们的数据保存在某种专用模型中并在那里进行操作,而不是将其拖出恰好显示它的 Ui 控件。重新跨越编辑时间;我使用移动网站,它比完整网站“实时”少得多;我可以向你保证,在我进行编辑以澄清价格是什么时,我不知道你的评论......
  • 否则你怎么能推理?我在哪里说使用盒装?
【解决方案2】:

更新:我认为现在的问题是另一个问题。我找不到可以给我查询结果的 MySql.Data.MySqlClient 库的方法。

public string sommaFattura(String costo)
        {
    MySqlCommand command = new MySqlCommand();
                String sumQuery = "SELECT SUM(`prezzo`) FROM `fatturetemp`";
                command.CommandText = sumQuery;
                command.Connection = conn.getConnection();
                command.Parameters.Add("@prezzo", MySqlDbType.Int32).Value = costo;
                conn.openConnection();
                conn.closeConnection();
}

给我 sumQuery 结果的命令如何。如果我找到这个命令,我可以把查询结果粘贴到文本框中

【讨论】:

    【解决方案3】:

    奇怪的是,您先转换为字符串,然后再转换为 int。

    int TOT = 0;
    for (int i = 0; i < dataGridView3.Rows.Count; i++)
    {
        if (!dataGridView3.Rows[i].IsNewRow &&
      int.TryParse(dataGridView3.Rows[i].Cells[6].Value.ToString(), out int v))
           TOT += v;
    }
    textBoxTot.Text = TOT.ToString();
    

    编辑:针对您更新的问题进行了编辑。无论如何,您都不应该在购买问题中提出问题:

    string sumQuery = "SELECT SUM(`prezzo`) FROM `fatturetemp`";
    decimal total = 0M;
    using (MySqlConnection cn = new MySqlConnection(" your connection string here "))
    using (MySqlCommand cmd = new MySqlCommand(sumQuery, cn))
    {
      cn.Open();
      total = Convert.ToDecimal(cmd.ExecuteScalar());
      cn.Close();
    }
    Console.WriteLine(total);
    

    【讨论】:

    • “cast”是指“parse”吗?人们不会说(在 c# 中)他们将字符串“转换”为 int
    • @CaiusJard,不,我是说演员阵容。您将一个包含整数值的对象作为示例进行转换,而不是解析。解析是不同的,看上面的例子,其中 Parse 是一个字符串到一个 int。
    • 你选择短语的方式,直接从谈论“将字符串转换为 int”到“你会用强制转换来做到这一点”听起来就像你在断言一个字符串可以被强制转换为 int。我想让你澄清一下演员表应该在源头上完成。您的代码没有帮助澄清,因为它随后提到了解析。你实际上没有在任何地方进行任何铸造。请让你的代码和你的话一致,因为这将使你的答案更加连贯和易于理解,也许有两个代码示例(一个强制转换和一个解析路由)
    • @CaiusJard,不,你在编造。我说“通常你会通过直接转换来做到这一点”,因为人们通常会期望绑定到那里的整数对象。我的代码清楚地表明 Parse 与字符串一起使用。我告诉我,我发现先转换为字符串很奇怪。
    • 我明白你为什么这么说,但这是一个非常普遍的模式;一个没有经验的开发人员正在从 DGV 单元中读取一些内容,它以 object 的形式出现 - 你和我都知道这是一个 int,我们可以说 (int)dgv[i, 6] 但某个地方的某个人会告诉他“将它串起来并解析它, 因为它会工作”.. 如果它是一个被装箱为对象或 int 的字符串,它会工作 - 另一件事,同样类型的开发人员会认为可以将数据填充到像dgv[i,6].Value = "Hello" 这样的数据网格视图中也将不太关心数据类型(-> NumberFormatException 任何人?)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多