Creating Custom Editors

The included editable attributes are build using the same system you can use to build your own.

Create a class inheriting from AbstractEditableAttribute, let visual studio generate the abstract methods:

using N2.Details;
using System.Web.UI;
 
namespace VanillaApplication.Models
{
     public class EditablePageDropDownAttribute : AbstractEditableAttribute
     {
           protected override Control AddEditor(Control container)
           {
                throw new NotImplementedException();
           }
 
           public override void UpdateEditor(N2.ContentItem item, Control editor)
           {
                throw new NotImplementedException();
           }
 
           public override bool UpdateItem(N2.ContentItem item, Control editor)
           {
                throw new NotImplementedException();
           }
     }
}

Implement AddEditor:

           protected override Control AddEditor(Control container)
           {
                // here we create the editor control and add it to the page
                DropDownList list = new DropDownList();
                list.ID = Name;
                list.DataTextField = "Title";
                list.DataValueField = "ID";
                list.DataSource = N2.Find.Items
                      .Where.AncestralTrail.NotLike("Trash%") // exclude trash
                      .MaxResults(1000) // keep a reasonable result size
                      .Filters(new AccessFilter()) // don't reveal secrets
                      .Select();
                list.DataBind();
                container.Controls.Add(list);
                return list;
           }

Now the available pages show up find but we need to persist what the manager selects: 

           public override void UpdateEditor(N2.ContentItem item, Control editor)
           {
                // here we update the editor control to reflect what was saved
                ContentItem selectedItem = item[Name] as ContentItem;
                if (selectedItem != null)
                {
                      DropDownList list = editor as DropDownList;
                      list.SelectedValue = selectedItem.ID.ToString();
                }
           }
 
           public override bool UpdateItem(N2.ContentItem item, Control editor)
           {
                // here we update the item from dropdown selection
                DropDownList list = editor as DropDownList;
                int selectedID = int.Parse(list.SelectedValue);
 
                ContentItem previouslySelected = item[Name] as ContentItem;
                if (previouslySelected != null && previouslySelected.ID == selectedID)
                      // no change
                      return false;
 
                item[Name] = Engine.Persister.Get(selectedID);
                return true;
           }

Let’s use the editable on some properties:

     public class HomePage : PageBase
     {
           [EditablePageDropDown]
           public virtual ContentItem AboutPage { get; set; }
 
           [EditablePageDropDown]
           public virtual ContentItem CookiePage { get; set; }
     }

Compile, refresh, and there they are.