Skip to content

Instantly share code, notes, and snippets.

@leon
Created August 22, 2011 11:39
Show Gist options
  • Save leon/1162196 to your computer and use it in GitHub Desktop.
Save leon/1162196 to your computer and use it in GitHub Desktop.
EPiServer Property usercontrol
using EPiServer.Core;
using EPiServer.Security;
using EPiServer.Web.PageExtensions;
using EPiServer.Web.PropertyControls;
using log4net;
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace EPiServer.Web.WebControls
{
[Designer("EPiServer.Web.WebControls.Design.PropertyDesigner, EPiServer.Design"), ValidationProperty("PropertyValue"), DefaultProperty("PropertyName"), ToolboxData("<{0}:Property runat=server></{0}:Property>")]
public class Property : WebControl, INamingContainer, IPageSource, IPageControl
{
private static readonly string _PROPERTYNAME;
private static readonly string _LASTTYPE;
private static readonly string _ISEDITMODE;
private static readonly string _ISEDITABLE;
private static readonly string _validationGroup;
private static readonly string _MISSINGMESSAGE;
private static readonly string _CUSTOMTAGNAME;
private static string[] _renderTypeNames;
private IPageSource _pageSource;
private PageData _currentPage;
private PageData _dataItem;
private string _errorMessage;
private PropertyData _propertyData;
private bool _isBound;
private bool _isDirty;
private static readonly ILog _log;
[Category("Appearance"), Bindable(true), DefaultValue(true)]
public bool DisplayMissingMessage
{
get
{
return this.ViewState[Property._MISSINGMESSAGE] == null || (bool)this.ViewState[Property._MISSINGMESSAGE];
}
set
{
this.ViewState[Property._MISSINGMESSAGE] = value;
}
}
public PropertyData InnerProperty
{
get
{
this.InitializeInnerProperty();
return this._propertyData;
}
set
{
this.Editable = false;
this._propertyData = value;
if (value != null)
{
this.PropertyName = this._propertyData.Name;
return;
}
this._currentPage = null;
}
}
internal PageData CurrentPage
{
get
{
this.InitializeInnerProperty();
return this._currentPage;
}
set
{
this._currentPage = value;
}
}
[Browsable(false)]
internal PropertyData PropertyData
{
get
{
return this._propertyData;
}
set
{
this._propertyData = value;
}
}
[Bindable(true), Category("Appearance"), DefaultValue(""), Editor("EPiServer.Design.TypeEditors.PropertyNameEditor, EPiServer.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]
public string PropertyName
{
get
{
return (string)(this.ViewState[Property._PROPERTYNAME] ?? string.Empty);
}
set
{
if (this.PropertyName != value)
{
this._propertyData = null;
this._isDirty = true;
this.ViewState[Property._PROPERTYNAME] = value;
}
}
}
public object PropertyValue
{
get
{
if (this.InnerProperty != null)
{
return this.InnerProperty.Value;
}
return null;
}
}
[DefaultValue(false)]
public bool EditMode
{
get
{
return this.ViewState[Property._ISEDITMODE] != null && (bool)this.ViewState[Property._ISEDITMODE];
}
set
{
this.ViewState[Property._ISEDITMODE] = value;
}
}
[Bindable(true), Category("Appearance"), DefaultValue(true)]
public bool Editable
{
get
{
this.InitializeInnerProperty();
return this.ViewState[Property._ISEDITABLE] == null || (bool)this.ViewState[Property._ISEDITABLE];
}
set
{
this.ViewState[Property._ISEDITABLE] = value;
}
}
[DefaultValue("")]
public string ValidationGroup
{
get
{
return this.ViewState[Property._validationGroup] as string;
}
set
{
this.ViewState[Property._validationGroup] = value;
}
}
public string CustomTagName
{
get
{
return (string)(this.ViewState[Property._CUSTOMTAGNAME] ?? string.Empty);
}
set
{
if (this.CustomTagName != value)
{
this.ViewState[Property._CUSTOMTAGNAME] = value;
this._isDirty = true;
}
}
}
[Browsable(false)]
public IPageSource PageSource
{
get
{
if (this._pageSource == null)
{
this.SetupPageSource();
}
return this._pageSource;
}
set
{
if (this._pageSource != value)
{
this._propertyData = null;
this._pageSource = value;
this._isDirty = true;
}
}
}
[DefaultValue(null), Editor("EPiServer.Web.WebControls.Design.PageReferenceTypeEditor, EPiServer.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]
public virtual PageReference PageLink
{
get
{
return (PageReference)(this.ViewState["_pageLink"] ?? PageReference.EmptyReference);
}
set
{
if (this.PageLink != value)
{
this._propertyData = null;
this._currentPage = null;
this._isDirty = true;
this.ViewState["_pageLink"] = value;
}
}
}
[DefaultValue(null), Editor("EPiServer.Design.TypeEditors.PropertyNameEditor, EPiServer.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]
public virtual string PageLinkProperty
{
get
{
return (string)(this.ViewState["_pageLinkProperty"] ?? string.Empty);
}
set
{
if (this.PageLinkProperty != value)
{
this._currentPage = null;
this._propertyData = null;
this._isDirty = false;
this.ViewState["_pageLinkProperty"] = value;
}
}
}
protected int BoundPageID
{
get
{
return (int)(this.ViewState["_boundPageLink"] ?? 0);
}
private set
{
this.ViewState["_boundPageLink"] = value;
}
}
private string RenderTypeString
{
get
{
return Property._renderTypeNames[(int)this.GetRenderType()];
}
}
PageData IPageSource.CurrentPage
{
get
{
return this._currentPage ?? this.PageSource.CurrentPage;
}
}
static Property()
{
Property._PROPERTYNAME = "_propertyName";
Property._LASTTYPE = "_lastType";
Property._ISEDITMODE = "_isEditMode";
Property._ISEDITABLE = "_isEditable";
Property._validationGroup = "ValidationGroup";
Property._MISSINGMESSAGE = "_displayMissingMessage";
Property._CUSTOMTAGNAME = "_customTagName";
Property._log = LogManager.GetLogger(typeof(Property));
RenderType[] array = (RenderType[])Enum.GetValues(typeof(RenderType));
Property._renderTypeNames = new string[(int)(array[array.Length - 1] + RenderType.Default)];
RenderType[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
RenderType renderType = array2[i];
Property._renderTypeNames[(int)renderType] = renderType.ToString();
}
}
public Property()
{
this._errorMessage = string.Empty;
this.EditMode = false;
this.Editable = true;
this.DisplayMissingMessage = true;
}
public Property(PropertyData prop) : this()
{
this._propertyData = prop;
}
private void InitializeInnerProperty()
{
if (this.PageSource == null || this._propertyData != null)
{
return;
}
if (this._currentPage == null)
{
this._currentPage = this.GetCurrentPageData();
if (this._currentPage == null)
{
return;
}
}
bool flag = false;
if (!string.IsNullOrEmpty(this.PropertyName))
{
this._propertyData = this._currentPage.Property[this.PropertyName];
if (this._propertyData != null && !this._propertyData.IsDynamicProperty)
{
flag = ((this._currentPage.PageLink == this.PageLink || PageReference.IsNullOrEmpty(this.PageLink)) && this._currentPage.GetSecurityDescriptor().HasAccess(PrincipalInfo.CurrentPrincipal, AccessLevel.Edit));
}
}
if (this.ViewState[Property._ISEDITABLE] != null)
{
this.ViewState[Property._ISEDITABLE] = (flag & (bool)this.ViewState[Property._ISEDITABLE]);
return;
}
this.ViewState[Property._ISEDITABLE] = flag;
}
private PageData GetCurrentPageData()
{
if (!PageReference.IsNullOrEmpty(this.PageLink))
{
if (this.PageSource.CurrentPage == null || this.PageLink != this.PageSource.CurrentPage.PageLink)
{
return this.PageSource.GetPage(this.PageLink);
}
return this.PageSource.CurrentPage;
}
else
{
if (!string.IsNullOrEmpty(this.PageLinkProperty))
{
PageData pageData = this._dataItem ?? this.PageSource.CurrentPage;
if (pageData == null)
{
throw new InvalidOperationException("PageLinkProperty specied when page context is missing.");
}
PageReference pageLink;
if (pageData.Property.TryGetValue<PageReference>(this.PageLinkProperty, out pageLink) && !PageReference.IsNullOrEmpty(pageLink))
{
return this.PageSource.GetPage(pageLink);
}
return null;
}
else
{
if (this._dataItem != null || this.BoundPageID > 0)
{
if (Property._log.IsDebugEnabled)
{
Property._log.Debug("EPiServer.Web.WebControls.Property: fetching PageData from BindingContainer");
}
if (this._dataItem == null)
{
this._dataItem = DataFactory.Instance.GetPage(new PageReference(this.BoundPageID));
}
return this._dataItem;
}
return this.PageSource.CurrentPage;
}
}
}
protected override void Render(HtmlTextWriter output)
{
if (this.InnerProperty != null)
{
this.EnsurePropertyControlsCreated();
this.RenderChildren(output);
return;
}
if (string.IsNullOrEmpty(this.PropertyName.Trim()))
{
output.WriteLine("[Error: PropertyName is not set.]");
return;
}
if (this._currentPage == null)
{
if (!this.DisplayMissingMessage)
{
return;
}
output.WriteLine("[Error: Property is contained in a page/control/template that does not have a current page.]");
return;
}
else
{
if (this._currentPage.Property[this.PropertyName] != null)
{
output.WriteLine("[Error: Unknown error.]");
return;
}
if (!this.DisplayMissingMessage)
{
return;
}
output.WriteLine("[Error: No property \"{0}\".]", this.PropertyName);
return;
}
}
private void SetupPageSource()
{
if (this._pageSource != null)
{
return;
}
if (this._pageSource == null)
{
this._pageSource = (this.Page as IPageSource);
}
if (this._pageSource == null)
{
this._pageSource = DataFactory.Instance;
}
}
protected override void CreateChildControls()
{
if (this.InnerProperty == null)
{
return;
}
RenderType renderType = this.GetRenderType();
if (this.Page.IsPostBack && this.ViewState[Property._LASTTYPE] != null && (string)this.ViewState[Property._LASTTYPE] != this.RenderTypeString)
{
base.ClearChildViewState();
}
IPropertyControl propertyControl = PropertyControlClassFactory.Instance.CreatePropertyControl(this.InnerProperty);
if (propertyControl != null)
{
this.Controls.Add((Control)propertyControl);
propertyControl.PropertyData = this.InnerProperty;
propertyControl.RenderType = renderType;
propertyControl.ValidationGroup = this.ValidationGroup;
propertyControl.Enabled = this.Enabled;
PropertyDataControl propertyDataControl = propertyControl as PropertyDataControl;
if (propertyDataControl != null)
{
propertyDataControl.AttributeSourceControl = this;
propertyDataControl.CustomTagName = this.CustomTagName;
}
propertyControl.SetupControl();
}
this.ViewState[Property._LASTTYPE] = renderType.ToString();
this._isDirty = false;
}
internal void ForceCreateChildControls()
{
this._propertyData = null;
this._currentPage = null;
base.ChildControlsCreated = false;
}
private RenderType GetRenderType()
{
if (this.EditMode)
{
return RenderType.Edit;
}
if (this.Editable && ContextMenu.Current != null && ContextMenu.Current.IsMenuEnabled && ContextMenu.Current.OnPageEditControl != null && ContextMenu.Current.OnPageEditControl.EditMode && PageReference.IsNullOrEmpty(this.PageLink) && !this.IsContainedInTemplate())
{
return RenderType.OnPageEdit;
}
return RenderType.Default;
}
private bool IsContainedInTemplate()
{
Control control = this;
while (control.Parent != null)
{
if (control.Parent is PageTemplateContainer)
{
return true;
}
if (control.Parent is IDataItemContainer && ((IDataItemContainer)control.Parent).DataItem is PageData)
{
return true;
}
control = control.Parent;
}
return false;
}
PageData IPageSource.GetPage(PageReference pageLink)
{
if (this._currentPage != null && pageLink == this._currentPage.PageLink)
{
return this._currentPage;
}
return this.PageSource.GetPage(pageLink);
}
PageDataCollection IPageSource.GetChildren(PageReference pageLink)
{
return this.PageSource.GetChildren(pageLink);
}
protected override void OnPreRender(EventArgs e)
{
if (this._isDirty || (!PageReference.IsNullOrEmpty(this.PageLink) && !this._isBound))
{
this.DataBind();
}
this.EnsurePropertyControlsCreated();
base.OnPreRender(e);
}
public void EnsurePropertyControlsCreated()
{
this.EnsureChildControls();
}
public override void DataBind()
{
try
{
base.OnDataBinding(EventArgs.Empty);
}
catch (NullReferenceException ex)
{
throw new NullReferenceException(string.Format("A error occurred while databinding \"{0}\", some values set on the page where null references [{2}]", this.UniqueID, base.GetType().ToString(), ex.Message));
}
bool flag = false;
object obj = null;
Control bindingContainer = base.BindingContainer;
while (bindingContainer != null && !this.QualifiesPageData(obj))
{
obj = DataBinder.GetDataItem(bindingContainer, out flag);
bindingContainer = bindingContainer.BindingContainer;
}
if (flag && obj != null && this.QualifiesPageData(obj))
{
if (this._pageSource == null && base.DesignMode)
{
IPageSource pageSource = (IPageSource)bindingContainer;
if (pageSource != null)
{
this._pageSource = pageSource;
}
}
this._dataItem = this.GetPageData(obj);
this.BoundPageID = this._dataItem.PageLink.ID;
}
if ((this.ViewState[Property._LASTTYPE] != null && (string)this.ViewState[Property._LASTTYPE] != this.RenderTypeString) || this._isDirty)
{
this.Controls.Clear();
base.ClearChildViewState();
base.ChildControlsCreated = true;
this.CreateChildControls();
this.TrackViewState();
}
this.EnsureChildControls();
for (int i = 0; i < this.Controls.Count; i++)
{
this.Controls[i].DataBind();
}
this._isBound = true;
}
private bool QualifiesPageData(object dataItem)
{
if (dataItem is PageData)
{
return true;
}
MenuItem menuItem = dataItem as MenuItem;
if (menuItem != null && string.Compare(menuItem.Value, typeof(PageData).FullName, StringComparison.InvariantCultureIgnoreCase) == 0)
{
PageReference pageReference;
return PageReference.TryParse(menuItem.DataPath, out pageReference);
}
PageSiteMapNode pageSiteMapNode = dataItem as PageSiteMapNode;
return pageSiteMapNode != null && pageSiteMapNode.CurrentPage != null;
}
private PageData GetPageData(object dataItem)
{
PageData pageData = dataItem as PageData;
if (pageData != null)
{
return pageData;
}
MenuItem menuItem = dataItem as MenuItem;
PageReference pageLink;
if (menuItem != null && PageReference.TryParse(menuItem.DataPath, out pageLink))
{
pageData = this.PageSource.GetPage(pageLink);
}
PageSiteMapNode pageSiteMapNode = dataItem as PageSiteMapNode;
if (pageSiteMapNode != null)
{
return pageSiteMapNode.CurrentPage;
}
return pageData;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment