May 3, 2012

Creating a Metro Tile Web Part

Metro style is the hot topic right now, so it is only right to take a look at how to make your SharePoint site more Metro too. You can build Metro blocks in the Content Editor Web Part, of course, but wouldn't it be so much easier to manage the tile content if the data was in a SharePoint list instead of being static content in a CEWP?

What you need in your (Empty SharePoint project) is
  • a List Definition and a List Instance for your source list - and I took it one step further by creating the Content Type for the list as well
  • the WebPart
  • your own CSS stylesheet in the mapped _Layouts folder
I am not going to go step by step through the process of creating these elements. For more info on creating SharePoint projects, webparts, content types, stylesheets etc. please check out some of my previous posts, e.g. in categories WebPartsBranding and Customization.

There's a whole lot of little things to do to put the thing together, and I will walk through the main points here.

For the Content Type (or the List Definition, if you are not creating a Content Type), you need to add the list fields and field references in its Elements.xml file. I used four fields in addtion to the Title field:
  • tile icon url field
  • tile content note field, setting the parameter HTMLEncode="true" to enable HTML tags in the content
  • tile background color (text) field for the background color as HEX code
  • tile url field (used to create a link wrapper around the icon and title)
In the ListDefinition Schema file you need to add the field references to the default view (BaseViewID 1) to show them in the AllItems view of the list. With the Fields and FieldRefs, remember that whether the tag has an endind tag or not really is of essence:
  • in Content Type Elements.xml both the Field and FieldRef tags are one-piece, eg:
    <Field Name="TileLink" DisplayName="Tile Hyperlink" ID="{GUID here}" Type="URL" Required="true"/>
    <FieldRef Name="TileLink"/>
  • in List Definition Schema.xml the FieldRef inside the Content Type element is as above, but the FieldRefs in the View elements are two-piece:
    <FieldRef Name="TileLink">
Also, remember to check the titles, descriptions and urls for the ContentType, ListDefinition and ListInstance, as well as the Web Part too, of course.

Once the list is done (and tested), add the Layout folder mapping to your project, and an empty CSS stylesheet in the project folder inside Layouts.

Then, add the WebPart to your project. In the WebPart .cs file, inside the CreateChildControls method, you need to
  • add the CSS reference
    If you are not trying to override corev4.css, this simple line is fine:
    and as for this project, this goes fine, since only our own classes need to be used. But if you need to make sure that the CSS is read after the corev4.css, see this blog post for the instructions.
  • retrieve the list items
    SPSite thisSite = SPContext.Current.Site;
    SPWeb rootsite = thisSite.RootWeb;
    SPList tilelist = rootsite.Lists["MetroTilesList"];
    SPListItemCollection items = tilelist.GetItems();
  • loop through the items 
    A foreach loop is fine. 
  • get field values for each item
    For any e.g. string type data (here the color and the content) you can use:
    string tilecontent = item["TileContent"].ToString();
    But if you try this with the hyperlink fields, due to the Description field embedded in it, you will get a double hyperlink value, separated by a comma, and that won't work. So you need to use the SPFieldUrlValue to get only the url value:
    SPFieldUrlValue TileUrlvalue = new SPFieldUrlValue(item["TileLink"].ToString());
    string tileurl = TileUrlvalue.Url;
    As for the title, you can simply refer to it with item.Title.
  • and create the html for the webpart
    Using LiteralControls you can quite easily create the HTML for each tile, using the field values in the places needed:

And then you need to create the CSS for the classes. The key points in the CSS here being:
  • the main element here is the tilecontainer, and for this 3 in a row, my CSS rules for it are:
    padding: 10px;
    margin: 5px; /* to create a consistent 10px space between tiles */
  • using the pseudo-element :nth-type-of(N), you can make the n:th (in this case the fourth) tile position itself neatly below the first tile instead of e.g. below the last tile of the row, if the tiles differ in height:
    div.tilecontainer:nth-of-type(3n+1) {clear: left;}
  • the background of the content span is white opaque so that it sits nicely with which ever color tile, but the IE7 and IE8 don't understand the rgba-rule, so I set the background as #dedede for them:
    background: rgba(255, 255, 255, 0.4);
    *background: #dedede;
Otherwise, the CSS is all about the positionings and colors and margins etc. of the contents of the tiles.

For more info on Metro style UX desing, see:

[See also: Add Properties to Your Web Part]


Anonymous said...

Great Article, with being New to SharePoint development, are you able to provide the Source Code to the article.

Anonymous said...

Hi, I appreciate your way, based on a list, is far more productive. But for a non-coding noob stuck withg editing CEWP could you please give an example of the code that might achieve a similar tile effect?

SM said...

Hi, both above, and thank you :)

I'm sorry but I cannot provide the complete source code for this webpart, at least not for the time being.

In CEWP, you can use simply div blocks with CSS styles to create the tiles.