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;
}
}
}
}