Created
August 22, 2011 11:39
-
-
Save leon/1162196 to your computer and use it in GitHub Desktop.
EPiServer Property usercontrol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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