How to get the formatted value of cell in GridView?

1 Answer 40 Views
GridView
Marian
Top achievements
Rank 2
Iron
Iron
Iron
Marian asked on 29 Apr 2024, 10:55 AM

Hello,
I have question about getting / copying formatted data in GridView. How can I get outside of GridView formatted value of cell? Second, how can I copy formatted data generally? I understand GridView uses virtualization and it formats data only for visual cells. But definitely there must be some methods for formatting data, that are at least used for formatting visual cells from underlying data. I have seen more forum threads and few samples in KB and documentation, I know there are Copying and CopyingCellClipboardContent events, but all samples demostrates manual formatting, for example lookup in combo box cell, or short time string for DateTime. I would like to get standard formatting, as it's displayed in GridView.

Maybe I should ask only to getting formatted value programatically, not standard Copy in GridView, but I have seen more samples for this. I was using WinForms DataGridView before, and there is FormattedValue property in cell object. I think there have to be a way how to get formatted value also in GridView, maybe by calling some method of GridView. About Copy, the best for me would be if I can get formatted value and do Copy manually, because I want to copy more data formats, formatted text representation and binary data for underlying data objects.

Btw. I was surprised GridView copies raw data and not formatted, I think standard and expected behavior for user is to copy what you can see, not some raw data.

1 Answer, 1 is accepted

Sort by
0
Dinko | Tech Support Engineer
Telerik team
answered on 02 May 2024, 08:14 AM

Hello Marian,

Thank you for reaching out to us.

To avoid any misunderstanding can you share how you have formatted the cell values? I have tested it with DateTime type and setting the FormatString property of the GridDateTimeColumn will format the cell value but it will not change the Value property of the cell. When I copy the cell, the visual cell text is copied. Is it possible to share more details about your set-up? How the cell values are formatted in your application?

In general, the Value property of the cell contains the value coming from the bound property. The Text property of the cell shows the visual text in the cell.

If you want to interfere in the coping operation, you can use the Copying event. Let's say the RadGridView is bound to a BindingList of custom objects. In the Copying event, you can cancel it and create your DataObject. Build your string from the bound collection (here you can apply your formatting) and pass the newly created DataObject to the Clipboard.SetDataObject() method.

private void RadGridView1_Copying(object sender, GridViewClipboardEventArgs e)
{
    if (e.Format == DataFormats.Text)
    {
        string result = string.Empty;
        var arr = myObjects.Select(x => x.Name).ToArray();
        result = string.Join(Environment.NewLine, arr);
        DataObject dataObject = new DataObject();
        dataObject.SetData(DataFormats.UnicodeText, false, result);
        dataObject.SetData(DataFormats.Text, false, result);
        Clipboard.SetDataObject(dataObject);
    }
    e.Cancel = true;
}

Regards,
Dinko | Tech Support Engineer
Progress Telerik

A brand new ThemeBuilder course was just added to the Virtual Classroom. The training course was designed to help you get started with ThemeBuilder for styling Telerik and Kendo UI components for your applications. You can check it out at https://learn.telerik.com
Marian
Top achievements
Rank 2
Iron
Iron
Iron
commented on 16 May 2024, 10:32 PM

Hello,
first, this is the screenshot of my test program (I have also attached it, project TelerikTestReal in solution).


I have two types of formatting, first formatting is by FormatString property of column, R/Fi/Min/Max columns have FormatString set to {0:F3}. There is also some formatting in CellFormatting event for hiding some cells and special formatting for replacing Test Type with subitem name for subitem rows.

I know Value property contains "raw" data from bound property, but there is no Text property in GridViewCellInfo object. So the first question was how to get formatted value of cell? I know GridView uses virtualization and it formats data only for visual cells, but is there any way to format value programatically?

		private void tsBtnTest_Click(object sender, EventArgs e)
		{
			GridViewCellInfo cellMin = radGridView1.Rows[3].Cells["colMin"];
			var val = cellMin.Value;
			//var text = cellMin.Text;
			GridViewCellInfo cellSub = radGridView1.Rows[8].Cells["colTestType"];
			var valSub = cellSub.Value;
		}

About copy, when I copy (by ctrl+C or context menu) some cells, I get raw data to clipboard. For example, if you copy cell in second row in Min column and paste it to notepad, you get '10,2', not '10,200' as it's formatted by FormatString property, or if you copy cell in Test Type column in row next to P7.2, it copies null, not 'Vyska' as it's formatted by CellFormatting event. Generally, I want to copy data as it's displayed in GridView, not the raw data from bound object properties. And about Copying event, I don't want to have own formatting, I would like to get output of standard formatting procedure, as it displayed in GridView.

But maybe we should discuss getting formatted value programatically first and not deal with copying.

Dinko | Tech Support Engineer
Telerik team
commented on 21 May 2024, 08:39 AM

The provided project is greatly appreciated. 

Thank you for elaborating on your first question. Indeed, the Text property is available only for the visual element. This comes from the visualization mechanism of the control. As the cells are virtualized only their underneath object is changed while scrolling. What you can do here is to use the Tag property of the GridViewCellInfo. In the CellFormatting, you can format the value and the result can be stored in the Tag property. Then you can use it at a later stage to get the formatted value.

private void radGridView1_CellFormatting(object sender, CellFormattingEventArgs e)
{
	if ((e.ColumnIndex < 0) || (e.RowIndex < 0))
		return;
. . . . . . . .// your code here
	(e.CellElement as GridDataCellElement).RowInfo.Cells[e.CellElement.ColumnIndex].Tag = e.CellElement.Text;
}

As for the copy functionality, as I mentioned, the copy mechanism works with the raw data. If you want to keep the approach with the formatting you will need to manually handle the copy event. What I could suggest instead is to format your data before applying it to the control. You could expose additional properties to your business object which will represent the format value. I think that this will be easier to implement and I hope that this way will work for you.

 

 

Marian
Top achievements
Rank 2
Iron
Iron
Iron
commented on 06 Jun 2024, 01:45 PM

Hello,
I am aware of fact, that GridView handles formatting only for visual cells. Also your example with storing value to Tag will probably work only for visible cells. Is there some method for applying formatting to cell programmatically? For example you have GetLookupValue method for combo box column, maybe there is something similar for formatting. DataGridView in WinForms also formats only visible cells, but it has virtual method GetFormattedValue, which handles formatting (text and style, and calls CellFormatting event), I can override it, or call it and get formatting for any cell. Is there something similar also in Telerik GridView?

Your suggestion to bind GridView to formatted data, I don't like this idea, you skip all formatting features of GridView, and also, it solves only text formatting, not style (background color etc).
Dinko | Tech Support Engineer
Telerik team
commented on 07 Jun 2024, 01:01 PM

The underneath cell object also exposes the Tag property. My approach will not set the Tag property of the visual cell but on the cell info object underneath the visual cell. In a few words, the following code will return GridViewCellInfo object:

(e.CellElement as GridDataCellElement).RowInfo.Cells[e.CellElement.ColumnIndex]

I am using its Tag property, not the property of the visual cell. 

Currently, the control does not expose a similar method to the GetFormattedValue of the MS DataGrid. The other approach which I can suggest is formatting the data before applying it to the control. However, you have stated that this one is not working for you.

 

 

Marian
Top achievements
Rank 2
Iron
Iron
Iron
commented on 07 Jun 2024, 05:44 PM | edited

Hello,

I have found out solution for standard formatting. I have looked to Telerik sources, trying to find out what GridView does with FormatString property. I have found out RadDataConverter class, which is used also for formatting in GridView. Its Format method gets 3 parameter:
- value, which I can get from GridViewCellInfo object
- targetType, which is set to typeof(string) by default in GridDataCellElement.ApplyFormatString
- converstionInfoProvider, which is also implemented by GridViewDataColumn

So, this code works for me to do standard formatting of value by FormatString property of column. Do you think this code is ok, or is there any problem in this?

private void tsBtnTest_Click(object sender, EventArgs e)
{
	GridViewCellInfo cellMin = radGridView1.Rows[3].Cells["colMin"];
	var val = cellMin.Value;

	var rdc = RadDataConverter.Instance;
	var col = radGridView1.Columns[cellMin.ColumnInfo.Index];
	object formattedValue = rdc.Format(val, typeof(string), col);
}

Problem is, that this code doesn't know anything about custom formatting in CellFormatting event, of course. I have tried to find out also what GridView does with CellFormatting event, but I haven't understood this, and it's also related to visual cells, of course. So, my idea is to create other method similar to my CellFormatting event handler, do the same with similar parameters, and use this for getting formatted value. And I can do similar with background color etc. I can use this method also in CellFormatting event handler, so that it doesn't have to be written twice. Something like this:

private void tsBtnTest_Click(object sender, EventArgs e)
{
	var min3 = GetFormattedValue(radGridView1, "colMin", 3); // 10,400
	var typ3 = GetFormattedValue(radGridView1, "colTestType", 3); // RelVyska
	var typ9 = GetFormattedValue(radGridView1, "colTestType", 9); // ____Tvar
}

private object GetFormattedValue(RadGridView gridView, string colName, int rowIndex)
{
	GridViewCellInfo cellInfo = gridView.Rows[rowIndex].Cells[colName];
	object value = cellInfo.Value;

	if (DoCustomCellFormatting(gridView, colName, rowIndex, value, out object formattedValue))
		return formattedValue;

	GridViewDataColumn col = gridView.Columns[colName];
	return DoStandardFormatting(value, col);
}

private object DoStandardFormatting(object value, IDataConversionInfoProvider conversionInfoProvider)
{
	RadDataConverter rdc = RadDataConverter.Instance;
	return rdc.Format(value, typeof(string), conversionInfoProvider);
}

private bool DoCustomCellFormatting(RadGridView gridView, string colName, int rowIndex, object value, out object formattedValue)
{
	formattedValue = value;

	var ed = gridView.Rows[rowIndex].DataBoundItem as TestParEditorItem;
	if (ed == null)
		return false;

	bool isSub = ed.IsSubItem;
	bool hasSub = !isSub && ed.SubItems.Count > 0;

	switch (colName)
	{
		case "colR":
		case "colFi":
		case "colComment":
			if (isSub)
			{
				formattedValue = "";
				return true;
			}
			break;

		case "colMin":
		case "colMax":
			if (hasSub)
			{
				formattedValue = "";
				return true;
			}
			break;

		case "colTestType":
			if (isSub)
			{
				formattedValue = "   " + ed.SubItemName;
				return true;
			}
			break;
	}

	return false;
}
What do you think about this solution? I have attached modified test project (TelerikTestReal) again, if you want to look on something. But I am really surprised no one expects formatted values in clipboard, it's the first thing I noticed when I pressed ctrl+C...
Dinko | Tech Support Engineer
Telerik team
commented on 12 Jun 2024, 07:41 AM

I appreciate your effort in trying to find a suitable solution and thank you for sharing it with the community. I have checked it and I agree that is looks reliable. Still, I would suggest testing it in different scenarios just to be sure that is covers all scenarios. If it works, you can consider using it in your application. 
Marian
Top achievements
Rank 2
Iron
Iron
Iron
commented on 18 Jun 2024, 06:14 PM

I see one scenario which it doesn't cover, when you do some formatting in custom columns. Is there any way to call custom formatting of column from outside of GridView? But I haven't tested custom columns yet, so maybe I can find out this later.
Dinko | Tech Support Engineer
Telerik team
commented on 20 Jun 2024, 01:34 PM

In a case, you want to force control to refresh itself, you can call the Refresh() method:

this.radGridView1.MasterTemplate.Refresh();

This way all the formatting events will be called. This way if you have a specific formatting that needs to be reflected in the RadGridView on a specific event, you can call the method.

Tags
GridView
Asked by
Marian
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Dinko | Tech Support Engineer
Telerik team
Share this question
or