Reputation: 313
I have a datagridview
that manipulate data from a DataBase. I have a column that has numeric value and each number is representation of a string value, for example,
0 => "group 1",
1 => "group 2"
and so on...
User must see this data as an readable format, meaning 0 => "group 1". something like this:
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"
in this link: (stackoverflow.com/questions/10314996/…) represent an idea, but I want something else. something more powerful. don't be shy, if there is no other way please tell me that there is not.
so in brief:
n => "group m"
.and one more thing: my programming language is c# in the windows app.
I hope to say what I mean.
thanks in advance.
Upvotes: 0
Views: 21462
Reputation: 205729
Let see what you got.
I want to display this data in the gridview without change in my db.
Great, this is how it should be. Data must be separated from the data representation.
cellformatting is not what I'm wanting here. cellformatting just formats the cell in terms of the data format.
Wrong!
Formatting is exactly what you need. One and the same data can be represented in many ways. For instance, one and the number or date value can be shown (formatted) using thousands ways (formats). This is exactly what string.Format (and other Format
) methods do. Another example is Checkbox
showing bool
value. Yet another example is ComboBox
displaying ValueMember
as DisplayMember
. Etc.
In fact your requirement is a variation of the Format
function and can be achieved with a Custom Numeric Format String. All you need is to set DataGridViewColumn.DefaultCellStyle property Format to "Group 0".
If the format wasn't enough, contrary to what some people say, the CellFormatting event is exactly what you need.
By default, the DataGridView control will attempt to convert a cell's value into a format suitable for display. For example, it will convert a numerical value into a string for display in a text box cell. You can indicate the formatting convention to use by setting the Format property of the DataGridViewCellStyle returned by properties such as the DefaultCellStyle property.
If the standard formatting is insufficient, you can customize the formatting by handling the CellFormattingevent. This event lets you indicate the exact display value as well as the cell styles, such as background and foreground color, to use for the cell display. This means you can handle this event for any kind of cell formatting, regardless of whether the cell value itself needs formatting.
The effect on the performance is negligible most of the time because the value is converted to string only when needed to be displayed on the screen, and the screen can a limited number of rows compared to the total number of rows (in case you have a huge data).
One of the advantages of the value/display text separation is that the grid sorting works correctly (by numeric rather than by text).
To conclude, don't be fooled to convert your data storage values for display. Every control has formatting capabilities, just use them. Since you asked for a simple way, Format
property is the simplest yet effective solution in your case.
Here is an example with 100,000 rows using both formatting approaches (comment the one and uncomment the other to play with). You can see that there is absolutely no performance issues, and GroupId
column sorting works correctly.
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);
}
}
}
Upvotes: 4
Reputation: 1008
Try this, you have to create a foreach loop to iterate through all items in the datagridview, this example shows you to change it for just the first record:
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;
}
Use this when you are populating the grid.
Hope this helps
Upvotes: 2
Reputation: 5822
sure, its simple.
you need to access the row index followed by the name of the column and set its value. For example:
this.dataGridView.Rows[0].Cells["FirstName"].Value = "billy";
this example accesses the first row and the cell "FirstName" and changes its value to "billy".
changes wont affect the DB but may affect the datasource binding thus causing the change on the datasource. instead you may want to not reference the datasource so the changes are not finally committed back to the DB when you operate with that datasource such as updating it.
Upvotes: 2