Details
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.
Summary and questions
so in brief:
- I want to display this data in the Gridview without any change in my db.
- I want the proposed format. Is there a simple way to make that format, meaning
n => "group m"
. - cellformatting is not what I’m wanting here. CellFormatting just formats the cell in terms of the data format. (msdn)
and one more thing: my programming language is c# in the windows app.
I hope to say what I mean.
thanks in advance.
Advertisement
Answer
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); } } }