SharePoint Blog - René Hézser

Anmelden  RSS Feed RSS Feed
Startet die Suche

Archive

Kategorien

Links

Andere Blogs




ITaCS GmbH


Custom Formatting in a SPGridView  

Mar 292008

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?

  1. Create a new class with a custom format method
  2. Add a DataColumn to your DataTable
    _DataTable.Columns.Add("Size", typeof(FileSize));
  3. Create a BoundField and add it to your SPGridView
  4. Add a new DataRow to your DataTable
    row["Size"] = new FileSize(file.Length);

If you look at my FileSize class you will notice that I am overriding the .ToString() method with a PadLeft. This is due to the fact that a string sorting is not the same as sorting a long. But if you put zeros in front of the long and then sort the resulting string, you will get the desired sorting.

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
   2:  {
   3:      private readonly long _Value;
   4:   
   5:      public long Value
   6:      {
   7:          get { return _Value; }
   8:      }
   9:   
  10:      public FileSize(long value)
  11:      {
  12:          _Value = value;
  13:      }
  14:   
  15:      public override string ToString()
  16:      {
  17:          //fill trailing zeros to be able to sort the size correctly
  18:          string value = _Value.ToString().PadLeft(12);
  19:          return value;
  20:      }
  21:   
  22:      // Write a custom Format method which shows the filesize "nicely"
  23:      public string ToString(string format, IFormatProvider fp)
  24:      {
  25:          if (format.Equals("nice"))
  26:              return SPUtility.FormatSize(_Value);
  27:          else 
  28:              return _Value.ToString(format, fp);
  29:      }
  30:  }
 

BoundField

   1:  BoundField size = new BoundField();
   2:  size.DataField = "Size";
   3:  size.HtmlEncode = false;
   4:  size.HeaderText = "Size";
   5:  size.SortExpression = "Size";
   6:  // use custom formatting, to display 1Kb instead of 1024
   7:  size.DataFormatString = "{0:nice}";
   8:   
   9:  _GridView.Columns.Add(size);
 
Update 24. March 2009
Filtering can be adjusted by changing the "FilteredDataSourcePropertyFormat" property to "{1}='{0}'";
Thanks to Volker for this one.
 
 
Technorati Tags: ,,
 
 
Posted by René Hézser | 1  Comment | Trackback Url  | 0  Links to this post | Bookmark this post with:        
Tags: Development, SharePoint
Technorati Tags: ,

Links to this post

Comments

commented on  Saturday, April 18, 2009  11:05 PM  by  Erik Burger
Hi Rene,

Excellent post! I think I might have the solution to your TODO there: implicit type conversion. I posted about this on my blog here: http://www.reversealchemy.net/2008/10/07/implicit-type-conversion/.

Let me know if this works for you, I'm curious if it will.

Regards,
Erik

Name *:
URL:
Email:
Kommentar:


CAPTCHA Image Validation