You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForm DataGridView自定义小数显示格式问题求助

解决C# WinForm DataGridView中double列小数位数显示与编辑保留问题

问题核心在于double类型本身不区分0.1和0.10的数值——两者在内存中是同一个值,DataGridView默认会基于数值本身格式化,因此会自动去除末尾无意义的0。要实现「默认按规则显示,编辑后保留用户输入的小数位数」的需求,需通过以下两种方案解决:

方案一:改用string类型存储数值(推荐)

将DataTable的列类型改为string,直接保留数值的字符串格式,同时通过事件控制显示规则和编辑验证。

步骤1:创建带string列的DataTable

DataTable valueTable = new DataTable();
// 用string类型存储数值,保留格式信息
valueTable.Columns.Add("数值", typeof(string));

// 添加示例数据
valueTable.Rows.Add("0.1");
valueTable.Rows.Add("0.9");
valueTable.Rows.Add("1.00");
valueTable.Rows.Add("0.11");

// 绑定到DataGridView
dataGridView1.DataSource = valueTable;
// 禁用默认格式化,让单元格直接显示字符串内容
dataGridView1.Columns["数值"].DefaultCellStyle.Format = null;

步骤2:处理CellFormatting事件(控制默认显示规则)

当单元格首次显示或刷新时,按规则格式化数值:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    // 仅处理目标列
    if (e.ColumnIndex != dataGridView1.Columns["数值"].Index || e.Value == null)
        return;

    if (double.TryParse(e.Value.ToString(), out double num))
    {
        // 0.1-0.9显示1位小数,其余情况显示2位
        string format = num >= 0.1 && num <= 0.9 ? "F1" : "F2";
        e.Value = num.ToString(format);
        e.FormattingApplied = true;
    }
}

步骤3:处理CellEndEdit事件(保留用户编辑的格式)

用户编辑完成后,解析输入并保留用户指定的小数位数:

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex != dataGridView1.Columns["数值"].Index)
        return;

    var cell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
    string input = cell.Value?.ToString().Trim() ?? string.Empty;

    if (!double.TryParse(input, out double num))
    {
        MessageBox.Show("请输入有效的数值");
        dataGridView1.CancelEdit();
        return;
    }

    // 判断用户输入的小数位数
    int inputDecimalPlaces = input.Contains('.') ? input.Split('.')[1].Length : 0;
    string formattedValue;

    // 如果用户输入了2位及以上小数,直接保留2位格式
    if (inputDecimalPlaces >= 2)
    {
        formattedValue = num.ToString("F2");
    }
    else
    {
        // 否则按默认规则格式化
        formattedValue = num >= 0.1 && num <= 0.9 ? num.ToString("F1") : num.ToString("F2");
    }

    cell.Value = formattedValue;
}

方案二:保留double列,额外存储小数位数

如果必须使用double类型存储数值,可以添加一列记录每个值的小数位数,通过事件联动控制显示。

步骤1:创建带双列的DataTable

DataTable valueTable = new DataTable();
valueTable.Columns.Add("数值", typeof(double));
// 隐藏列,用于存储对应数值的小数位数
valueTable.Columns.Add("小数位数", typeof(int));

// 添加示例数据(数值+对应小数位数)
valueTable.Rows.Add(0.1, 1);
valueTable.Rows.Add(0.9, 1);
valueTable.Rows.Add(1.00, 2);
valueTable.Rows.Add(0.11, 2);

dataGridView1.DataSource = valueTable;
// 隐藏小数位数列
dataGridView1.Columns["小数位数"].Visible = false;

步骤2:处理CellFormatting事件

根据存储的小数位数格式化显示:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.ColumnIndex != dataGridView1.Columns["数值"].Index || e.RowIndex < 0)
        return;

    var row = ((DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem).Row;
    double num = (double)row["数值"];
    int decimalPlaces = (int)row["小数位数"];

    e.Value = num.ToString($"F{decimalPlaces}");
    e.FormattingApplied = true;
}

步骤3:处理CellEndEdit事件

更新数值和对应的小数位数:

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex != dataGridView1.Columns["数值"].Index)
        return;

    var cell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
    string input = cell.Value?.ToString().Trim() ?? string.Empty;

    if (!double.TryParse(input, out double num))
    {
        MessageBox.Show("请输入有效的数值");
        dataGridView1.CancelEdit();
        return;
    }

    var row = ((DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem).Row;
    int inputDecimalPlaces = input.Contains('.') ? input.Split('.')[1].Length : 0;

    // 更新数值
    row["数值"] = num;
    // 更新小数位数:用户输入了位数则用输入的,否则按默认规则
    row["小数位数"] = inputDecimalPlaces >= 1 ? inputDecimalPlaces : (num >= 0.1 && num <= 0.9 ? 1 : 2);
}

内容的提问来源于stack exchange,提问作者Enes Karakaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:05:20