My first Kentico page resulted in a bit of a mess. It involved lots of WebPartZones, and then each zone had a WebPart in that would then be bound to the CMSContext.CurrentDocument.SomeField. This allowed me to bind the name, description, image etc…
Unfortunately it quickly looks a mess in CMSDesk, is quite time consuming and it just a bit of a pain working in CMSDesk for all this content. I asked around and my team pointed out that I could do in-line data binding like so:
1 2 3 4 |
<div class="imageInfo"> <h1><%= CMSContext.CurrentDocument.GetStringValue("Title", "{Title}") %></h1> <p><%= CMSContext.CurrentDocument.GetStringValue("Description", String.Empty) %></p> </div> |
The problem is at this point things like the Designer view in CMSDesk will frequently complain with the error:
The Controls collection cannot be modified because the control contains code blocks
This is rather annoying, and consequently developers have either used the approach of adding lots of WebParts (the norm) or sometimes assigning values in the code behind. What I find easier however is to change the syntax slightly to use data binding:
1 2 3 4 |
<div class="imageInfo"> <h1><%# CMSContext.CurrentDocument.GetStringValue("Title", "{Title}") %></h1> <p><%# CMSContext.CurrentDocument.GetStringValue("Description", String.Empty) %></p> </div> |
Now this won’t work either directly, because your page probably hasn’t been data bound. The easy way to fix this is to ensure you call DataBind(). In my case I wanted to put this in the masterpage, but the masterpage from Kentico didn’t feature a code behind file that I could easily modify so I simply changed the master page inherits it like so:
1 |
<%@ Control Language="C#" Inherits="MasterPageLayout" %>
|
Now in page load I can call DataBind:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; using CMS.PortalControls; namespace NetC.BurtonRoofing { /// <summary> /// Code behind for the Master Page /// <remarks>Allows the use of markup in the ascx such as </remarks> /// </summary> public class MasterPageLayout : CMSAbstractLayout { /// <summary> /// Raises the <see cref="E:Load" /> event. /// </summary> /// <remarks>Calls the DataBind method for the page</remarks> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); Page.DataBind(); } } } |
This makes data binding nice and simple, keeping your binding in your designer code without needing to mess around with WebPartZones.