如何在运行时更改gridview中单元格的值?

时间:2013-11-23 20:53:21

标签: c# sql .net gridview

我有一个datagridview来操纵DataBase中的数据。我有一个具有数值的列,每个数字都表示一个字符串值,例如

0 => "group 1", 
1 => "group 2" 
and so on...

用户必须将此数据视为可读格式,即0 => “第1组”。像这样的东西:

id          priceGroupID
----------- ------------
1234        -1 => "group -1"
36968       0  => "group  0"
1           2  => "group  2"
2           2  => "group  2"
3           2  => "group  2"
1003        2  => "group  2"

在这个链接中:( stackoverflow.com/questions/10314996/…)代表一个想法,但我想要别的东西。更强大的东西。不要害羞,如果没有别的办法,请告诉我没有。

简而言之:

  • 我想在Gridview中显示这些数据,而我的数据库没有任何变化。
  • 我想要提议的格式。是否有一种简单的方法来制作该格式,即n => "group m"
  • cellformatting不是我想要的。 CellFormatting只是根据数据格式格式化单元格。 (msdn

还有一件事:我的编程语言是windows应用程序中的c#。

我希望说出我的意思。

提前感谢。

3 个答案:

答案 0 :(得分:4)

让我们看看你得到了什么。

  

我想在gridview中显示这些数据而不改变我的数据库。

很好,这应该是这样的。 数据必须与数据表示分开。

  

cellformatting并不是我想要的。 cellformatting只是根据数据格式格式化单元格。

错误!

格式化正是您所需要的。可以用许多方式表示同一个数据。例如,可以使用数千种方式(格式)显示(格式化)一个数字或日期值。这正是string.Format(和其他Format)方法的作用。另一个例子是Checkbox显示bool值。另一个示例是ComboBoxValueMember显示为DisplayMember。等

事实上,您的要求是Format功能的变体,可以使用Custom Numeric Format String来实现。您只需将DataGridViewColumn.DefaultCellStyle属性Format设置为"组0"。

如果格式不够,与某些人说的相反,CellFormatting事件正是您所需要的。

  

默认情况下,DataGridView控件将尝试将单元格的值转换为适合显示的格式。例如,它会将数值转换为字符串,以便在文本框单元格中显示。您可以通过设置由DefaultCellStyle属性等属性返回的DataGridViewCellStyle的Format属性来指定要使用的格式约定。

     

如果标准格式不足,您可以通过处理CellFormattingevent来自定义格式。此事件允许您指示用于单元格显示的确切显示值以及单元格样式(如背景和前景色)。这意味着无论单元格值本身是否需要格式化,您都可以针对任何类型的单元格格式处理此事件。

在大多数情况下,对性能的影响可以忽略不计,因为只有当需要在屏幕上显示时才将值转换为字符串,并且屏幕与行总数相比可以行数量有限(以防万一)你有一个巨大的数据。)

值/显示文本分离的一个优点是网格排序正常工作(通过数字而不是文本)。

总而言之,不要愚弄转换您的数据存储值以供显示。每个控件都有格式化功能,只需使用它们。由于您要求一种简单的方法,Format属性是您案例中最简单但最有效的解决方案。

这是一个使用两种格式化方法的100,000行的示例(注释一个并取消注释另一个要使用)。您可以看到绝对没有性能问题,GroupId列排序正常工作。

using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;

namespace Samples
{
    static class Program
    {
        static void UseFormat(DataGridView dg)
        {
            dg.ColumnAdded += (sender, e) =>
            {
                if (e.Column.DataPropertyName == "GroupId")
                {
                    e.Column.DefaultCellStyle.Format = "Group 0";
                }
            };
        }

        static void UseCellFormatting(DataGridView dg)
        {
            dg.CellFormatting += (sender, e) =>
            {
                if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
                {
                    var column = dg.Columns[e.ColumnIndex];
                    if (column.DataPropertyName == "GroupId" && e.Value != null)
                    {
                        e.Value = "Group " + e.Value.ToString();
                        e.FormattingApplied = true;
                    }
                }
            };
        }

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form = new Form();
            var dg = new DataGridView { Dock = DockStyle.Fill, Parent = form, ReadOnly = true, AllowUserToAddRows = false };
            UseFormat(dg);
            //UseCellFormatting(dg);
            var data = new DataTable();
            data.Columns.Add("Id", typeof(int));
            data.Columns.Add("GroupId", typeof(int));
            var groupIds = Enumerable.Range(0, 15).ToArray();
            for (int i = 0; i < 100000; i++)
                data.Rows.Add(i, groupIds[i % groupIds.Length]);
            dg.DataSource = data;
            Application.Run(form);
        }
    }
}

答案 1 :(得分:2)

确定,这很简单。

您需要访问行索引,后跟列名并设置其值。例如:

this.dataGridView.Rows[0].Cells["FirstName"].Value = "billy";

此示例访问第一行和单元格“FirstName”并将其值更改为“billy”。

更改不会影响数据库,但可能会影响数据源绑定,从而导致数据源发生更改。相反,您可能不想引用数据源,因此当您使用该数据源进行操作(例如更新数据源)时,更改不会最终提交回数据库。

答案 2 :(得分:2)

试试这个,你必须创建一个foreach循环来迭代datagridview中的所有项目,这个例子显示你只为第一个记录改变它:

int groupIdentifier = this.dataGridView.Rows[0].Cells["Group"].Value;

this.dataGridView.Rows[0].Cells["Group"].Value = GetGroupName(groupIdentifier);

List<Groups> ListGroups = new List<Groups>();

private string GetGroupName(int groupIdentifier)
{
    var group = ListGroups.FirstOrDefault(g=>g.Id == groupIdentifier);
    return group.Name;
}

填充网格时使用此选项。

希望这有帮助