Multiproperty from behind

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

One thought on “Multiproperty from behind

Leave a reply to Multiproperty from behind | EPiServer CMS: The Unofficial Website Cancel reply