Okay this is my first tech-blog so bare with me. Please send comments if some things I write are not properly explained.
Starting
A colleague of mine had a problem with a list of pages using Itera.MultiProperty.
He had started to make two CustomProperties as explained in the examples in the Itera.MultiProperty.Examples namespace in Itera.MultiProperty.dll:
PropertyLegacyLinks inheriting from PropertyMulitBase
[EPiServer.PlugIn.PageDefinitionTypePlugIn(DisplayName = "Legacy links", Description = "List of legacy links")] public class PropertyLegacyLinks : PropertyMulitBase { PropertyDataCollection _innerPropertyCollection; object lockObject = new object(); public override PropertyDataCollection BasePropertys { get { if (_innerPropertyCollection == null) { lock (lockObject) { PropertyDataCollection _new = new PropertyDataCollection(); _new.Add(Translate("/legacylinksproperty/legacylink"), new PropertyLegacyLink()); _innerPropertyCollection = _new; } } return _innerPropertyCollection; } } }
PropertyLegacyLink inheriting from PropertySingleBase
public class PropertyLegacyLink : PropertySingleBase { PropertyDataCollection _innerPropertyCollection; object lockObject = new object(); protected override PropertyDataCollection InnerPropertyCollection { get { if (_innerPropertyCollection == null) { lock (lockObject) { PropertyDataCollection _new = new PropertyDataCollection(); _new.Add(Translate("/legacylinksproperty/formerlink"), new PropertyString("")); _new.Add(Translate("/legacylinksproperty/currentlink"), new PropertyPageReference()); _innerPropertyCollection = _new; } } return _innerPropertyCollection; } set { lock (lockObject) { _innerPropertyCollection = value; } } } }
PropertyLegacyLink contained a String (<= 255) and a PageReference which should be listed on the page.
Frontend
He had made it work and render according to Anders Hattestad’s blog post <EPiServer:Property on steroids /> where he used the <Itera:Property> iterating through the PropertyLegacyLinks Property here called “Legacy”,
Inside the Itera:Property there was another Itera:Property iterating the PropertyLegacyLink printing its values.
<Itera:Property ID="PropertyCtrl" runat="server" SuppressEmpty="false" PropertyName="Legacy"> <ItemTemplate> <Itera:Property PropertyName="this.PropertyCollection" SuppressEmpty="true" runat="server" EnableViewState="false"> <HeaderTemplate> <table border="1"> <tr> <th colspan="2"> Legacy Link </th> </tr> </HeaderTemplate> <ItemTemplate> <tr> <td> {this.Name} </td> <td> {this.Value} </td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </Itera:Property> </ItemTemplate> </Itera:Property>
Rendering
Legacy Link | |
---|---|
LegacyLink_d43da6749d2247fe9d038c69ae4be1ff | Tidigare länk
16 |
LegacyLink_0c6a5fc3e2344c74a452e63ea20c833b | Äldre länk
15 |
Very nice if you want to see what your MultiProperty contains and you can probably work some more with the Itera:MultiProperty to make it look good. But what if we want to fetch the data from Backend?
Backend
After some digging in Red Gate’s Reflector I found out that the MultiProperty is a PropertyDataCollection containing rows with PropertyDataCollection containing the Properties.
What we need to do is iterate through the first PropertyDataCollection by using
PropertyLegacyLinks legacies = (PropertyLegacyLinks)CurrentPage.Property["Legacy"]; PropertyDataCollection legacyLinksCollection = legacies.PropertyCollection; PropertyDataCollection legacyLinkCollection; foreach (PropertyLegacyLink item in legacyLinksCollection) { legacyLinkCollection = item.PropertyCollection; }
Where you can get your string through (string)legacyLinkCollection[0].Value and (PageReference)legacyLinkCollection[1].Value.
Polishing
Using PropertyDataCollections needs alot of casting. So what I would suggest is giving the PropertyLegacyLinks a List<PropertyLegacyLink> as a Property and giving PropertyLegacyLink a string and a PageReference Property, such as this:
[EPiServer.PlugIn.PageDefinitionTypePlugIn(DisplayName = "Legacy links", Description = "List of legacy links")] public class PropertyLegacyLinks : PropertyMulitBase { PropertyDataCollection _innerPropertyCollection; object lockObject = new object(); private List<PropertyLegacyLink> _legacyLinks; public List<PropertyLegacyLink> LegacyLinks { get { if (_legacyLinks == null) { _legacyLinks = new List<PropertyLegacyLink>(); for (int i = 0; i < BasePropertys.Count; i++) { PropertyLegacyLink item = BasePropertys[i] as PropertyLegacyLink; _legacyLinks.Add(item); } } } return _legacyLinks; } } public override PropertyDataCollection BasePropertys { get { if (_innerPropertyCollection == null) { lock (lockObject) { PropertyDataCollection _new = new PropertyDataCollection(); _new.Add(Translate("/legacylinksproperty/legacylink"), new PropertyLegacyLink()); _innerPropertyCollection = _new; } } return _innerPropertyCollection; } } }
and
public class PropertyLegacyLink : PropertySingleBase { PropertyDataCollection _innerPropertyCollection; object lockObject = new object(); private string _formerlink; public string FormerLink { get { if (_formerlink == null) { _formerlink = this.PropertyCollection[0].Value as string ?? string.Empty; } return _formerlink; } set { _formerlink = value; } } private PageReference _currentLink; public PageReference CurrentLink { get { if (_currentLink == null) { _currentLink = this.PropertyCollection[1].Value as PageReference ?? PageReference.EmptyReference; } return _currentLink; } set { _currentLink = value; } } protected override PropertyDataCollection InnerPropertyCollection { get { if (_innerPropertyCollection == null) { lock (lockObject) { PropertyDataCollection _new = new PropertyDataCollection(); _new.Add(Translate("/legacylinksproperty/formerlink"), new PropertyString("")); _new.Add(Translate("/legacylinksproperty/currentlink"), new PropertyPageReference()); _innerPropertyCollection = _new; } } return _innerPropertyCollection; } set { lock (lockObject) { _innerPropertyCollection = value; } } } }
[…] Visit link: Multiproperty from behind […]