Custom Formatting in a SPGridView
One of the problems with the SPGridView occurs, if you display e.g. the file size of files, and try to sort with this information. The internal value you get from a SPFile of FileInfo Object shows you the length of the file in bytes. This is great if you want to sort this column. But what if you choose to display the long value with the amount of bytes for a file not as the value, but formatted with SPUtility.FormatSize(file.length)?
Well, you cannot sort for this column anymore, because sorting System.string values is not the same as sorting the original file size which is a System.long.
So what can you do to a) format the file size nicely and b) still be able to sort your entries with their file sizes?
- Create a new class with a custom format method
- Add a DataColumn to your DataTable
_DataTable.Columns.Add(“Size”, typeof(FileSize));-
Create a BoundField and add it to your SPGridView
- Add a new DataRow to your DataTable
row[“Size”] = new FileSize(file.Length);
- Add a new DataRow to your DataTable
-
- Add a DataColumn to your DataTable
The big TODO with this solution is, that you have to disable the filtering for the “Size” column. This is due to the fact that we use our own class in the DataTable, which does not work with the FilteredDataSourcePropertyFormat = “{1} LIKE ‘{0}’" from the SPGridView, because it is not a string. “System.Data.EvaluateException: Cannot perform ‘Like’ operation on RH.FileLink and System.String”
new class
1: class FileSize : IFormattable
<span class=lnum> 2: </span>{
3: private readonly long _Value;
<span class=lnum> 4: </span>
5: public long Value
<span class=lnum> 6: </span> {
7: get { return _Value; }
<span class=lnum> 8: </span> }
9:
<span class=lnum> 10: </span> <span class=kwrd>public</span> FileSize(<span class=kwrd>long</span> <span class=kwrd>value</span>)
11: {
<span class=lnum> 12: </span> _Value = <span class=kwrd>value</span>;
13: }
<span class=lnum> 14: </span>
15: public override string ToString()
<span class=lnum> 16: </span> {
17: //fill trailing zeros to be able to sort the size correctly
<span class=lnum> 18: </span> <span class=kwrd>string</span> <span class=kwrd>value</span> = _Value.ToString().PadLeft(12);
19: return value;
<span class=lnum> 20: </span> }
21:
<span class=lnum> 22: </span> <span class=rem>// Write a custom Format method which shows the filesize "nicely"</span>
23: public string ToString(string format, IFormatProvider fp)
<span class=lnum> 24: </span> {
25: if (format.Equals("nice"))
<span class=lnum> 26: </span> <span class=kwrd>return</span> SPUtility.FormatSize(_Value);
27: else
<span class=lnum> 28: </span> <span class=kwrd>return</span> _Value.ToString(format, fp);
29: }
<span class=lnum> 30: </span>}
BoundField
1: BoundField size = new BoundField();
<span class=lnum> 2: </span>size.DataField = <span class=str>"Size"</span>;
3: size.HtmlEncode = false;
<span class=lnum> 4: </span>size.HeaderText = <span class=str>"Size"</span>;
5: size.SortExpression = "Size";
<span class=lnum> 6: </span><span class=rem>// use custom formatting, to display 1Kb instead of 1024</span>
7: size.DataFormatString = "{0:nice}";
<span class=lnum> 8: </span>
9: _GridView.Columns.Add(size);
Update 24. March 2009