//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------ using System.Web.Mobile; using System.Web.UI; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design; using System.Globalization; using System.Security.Permissions; namespace System.Web.UI.MobileControls { /// [ ControlBuilderAttribute(typeof(FormControlBuilder)), DefaultEvent("Activate"), Designer(typeof(System.Web.UI.Design.MobileControls.FormDesigner)), DesignerAdapter(typeof(System.Web.UI.MobileControls.Adapters.HtmlFormAdapter)), PersistChildren(true), ToolboxData("<{0}:Form runat=\"server\">"), ToolboxItem("System.Web.UI.Design.WebControlToolboxItem, " + AssemblyRef.SystemDesign) ] [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] public class Form : Panel, ITemplateable, IPostBackEventHandler { private static readonly Object EventActivate = new Object(); private static readonly Object EventDeactivate = new Object(); private static readonly Object EventPaginated = new Object(); private PagerStyle _pagerStyle; private int _cachedCurrentPage = -1; private Panel _headerContainer = null; private Panel _footerContainer = null; private Panel _scriptContainer = null; /// public Form() { _pagerStyle = new PagerStyle(); _pagerStyle.SetControl(this); } /// /// /// /// Gets or sets the title used to identify the form. /// /// /// /// /// The title may be rendered as part of the form, on devices /// that support a title separate from page content (e.g., on /// the title bar of a browser using the title tag in HTML). /// /// [ Bindable(true), DefaultValue(""), MobileCategory(SR.Category_Appearance), MobileSysDescription(SR.Form_Title) ] public String Title { get { String s = (String) ViewState["Title"]; return((s != null) ? s : String.Empty); } set { ViewState["Title"] = value; } } /// [ Bindable(true), DefaultValue(FormMethod.Post), MobileCategory(SR.Category_Behavior), MobileSysDescription(SR.Form_Method) ] public FormMethod Method { get { Object o = ViewState["Method"]; return ((o != null) ? (FormMethod)o : FormMethod.Post); } set { ViewState["Method"] = value; } } /// [ Bindable(true), DefaultValue(""), Editor(typeof(System.Web.UI.Design.UrlEditor), typeof(System.Drawing.Design.UITypeEditor)), MobileCategory(SR.Category_Behavior), MobileSysDescription(SR.Form_Action) ] public String Action { get { String s = (String) ViewState["Action"]; return((s != null) ? s : String.Empty); } set { ViewState["Action"] = value; } } /// [ DefaultValue(null), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MobileCategory(SR.Category_Style), MobileSysDescription(SR.Form_PagerStyle), NotifyParentProperty(true) ] public PagerStyle PagerStyle { get { return _pagerStyle; } } /// protected void RaisePostBackEvent(String eventArgument) { // If the event argument is all numeric, then it's a pager event. bool notANumber = false; int length = eventArgument.Length; for (int i = 0; i < length; i++) { char c = eventArgument[i]; if (c < '0' || c > '9') { notANumber = true; break; } } if (!notANumber && length > 0) { try { int page = Int32.Parse(eventArgument, CultureInfo.InvariantCulture); if (page > 0) { int oldPage = _currentPage; if(_cachedCurrentPage == -1) { _currentPage = page; _cachedCurrentPage = page; } // currentpage may != page if page is invalid OnPageChange(oldPage, _currentPage); } return; } catch { // Argument may be invalid number, so let adapter handle it. } } Adapter.HandlePostBackEvent(eventArgument); } /// [ MobileCategory(SR.Category_Action), MobileSysDescription(SR.Form_OnActivate) ] public event EventHandler Activate { add { Events.AddHandler(EventActivate, value); } remove { Events.RemoveHandler(EventActivate, value); } } /// [ MobileCategory(SR.Category_Action), MobileSysDescription(SR.Form_OnDeactivate) ] public event EventHandler Deactivate { add { Events.AddHandler(EventDeactivate, value); } remove { Events.RemoveHandler(EventDeactivate, value); } } /// [ MobileCategory(SR.Category_Action), MobileSysDescription(SR.Form_OnPaginated) ] public event EventHandler Paginated { add { Events.AddHandler(EventPaginated, value); } remove { Events.RemoveHandler(EventPaginated, value); } } /// [ Bindable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public Panel Header { get { return _headerContainer; } } /// [ Bindable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public Panel Footer { get { return _footerContainer; } } /// [ Bindable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public Panel Script { get { return _scriptContainer; } } internal bool Activated = false; internal void FireActivate(EventArgs e) { if (!Activated) { Activated = true; OnActivate(e); } } internal void FireDeactivate(EventArgs e) { if (Activated) { Activated = false; OnDeactivate(e); } } /// protected virtual void OnActivate(EventArgs e) { EventHandler onActivate = (EventHandler)Events[EventActivate]; if (onActivate != null) { onActivate(this, e); } } /// protected virtual void OnDeactivate(EventArgs e) { EventHandler onDeactivate = (EventHandler)Events[EventDeactivate]; if (onDeactivate != null) { onDeactivate(this, e); } } /// public virtual bool HasActivateHandler() { return Events[EventActivate] != null; } /// public virtual bool HasDeactivateHandler() { return Events[EventDeactivate] != null; } /// protected virtual void OnPaginated(EventArgs e) { EventHandler onPaginated = (EventHandler)Events[EventPaginated]; if (onPaginated != null) { onPaginated(this, e); } } /// protected override void OnInit(EventArgs e) { if (MobilePage != null && !MobilePage.DesignMode) { // Be sure we're not included in any other Forms. for (Control control = this.Parent; control != null; control = control.Parent) { Form parentForm = control as Form; if (parentForm != null) { throw new Exception(SR.GetString(SR.Form_NestedForms, this.ID, parentForm.ID)); } } } base.OnInit(e); } /// public IList GetLinkedForms(int optimumPageWeight) { // Always add itself to the list as the first one UniqueSet set = new UniqueSet(); set.Add(this); // If the form has a deactivate handler, then we // can't send the form with linked forms, because server interaction // is necessary to move between forms. if (HasDeactivateHandler()) { return set; } // Will stop once no new forms are added in a pass, or has // reached the optimum page weight. int totalWeight = 0; int i; // negative means the caller doesn't care about the weight bool checkWeight = optimumPageWeight >= 0; for (i = 0; i < set.Count; i++) { Form form = (Form)set[i]; if (checkWeight) { totalWeight += form.GetVisibleWeight(); if (totalWeight > optimumPageWeight) { break; } } form.AddLinkedForms(set); } // More forms may have been linked than the total weight allows. // Remove these. if (i != 0 && // i == 0 means only one form is in the list i < set.Count) { for (int j = set.Count - 1; j >= i; j--) { set.RemoveAt(j); } } return set; } /// public override void CreateDefaultTemplatedUI(bool doDataBind) { ITemplate headerTemplate = GetTemplate(Constants.HeaderTemplateTag); ITemplate footerTemplate = GetTemplate(Constants.FooterTemplateTag); ITemplate scriptTemplate = GetTemplate(Constants.ScriptTemplateTag); if (scriptTemplate != null) { _scriptContainer = new TemplateContainer(); // The scriptTemplate is not added to the controls tree, so no need to do // CheckedInstantiateTemplate to check for infinite recursion. scriptTemplate.InstantiateIn(_scriptContainer); _scriptContainer.EnablePagination = false; } if (headerTemplate != null) { _headerContainer = new TemplateContainer(); CheckedInstantiateTemplate (headerTemplate, _headerContainer, this); _headerContainer.EnablePagination = false; Controls.AddAt(0, _headerContainer); } if (footerTemplate != null) { _footerContainer = new TemplateContainer(); CheckedInstantiateTemplate (footerTemplate, _footerContainer, this); _footerContainer.EnablePagination = false; Controls.Add(_footerContainer); } // Do not call base.CreateDefaultTemplatedUI(), since we don't want // Forms to have ContentTemplates as Panels do. } private int _pageCount = -1; /// [ Bindable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public int PageCount { get { // If not yet paginated, it's okay to return -1. return _pageCount; } } private int _currentPage = 1; /// [ Bindable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public int CurrentPage { get { return _currentPage; } set { if (_currentPage != value) { OnPageChange (_currentPage, value); } _currentPage = value; _cachedCurrentPage = _currentPage; } } /// [ Bindable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override bool BreakAfter { get { if (MobilePage.DesignMode) { return true; } throw new Exception( SR.GetString(SR.Form_PropertyNotAccessible, "BreakAfter")); } set { throw new Exception( SR.GetString(SR.Form_PropertyNotSettable, "BreakAfter")); } } /// protected override void OnPreRender(EventArgs e) { // AUI 3630 base.OnPreRender(e); _pageCount = PaginateForm(); // Clamp to 1 < _currentPage <= PageCount int page = Math.Max(Math.Min(_currentPage, _pageCount), 1); if(_currentPage != page) { _currentPage = page; } if ((Paginate) || (ControlToPaginate != null)) { OnPaginated(new EventArgs()); } } /// protected override void Render(HtmlTextWriter writer) { MobilePage.EnterFormRender(this); OnRender(writer); MobilePage.ExitFormRender(); } private int PaginateForm() { int pageWeight = MobilePage.Adapter.OptimumPageWeight; if (Header != null) { pageWeight -= Header.VisibleWeight; } if (Footer != null) { pageWeight -= Footer.VisibleWeight; } if (pageWeight <= 0) { // pageWeight = MobilePage.Adapter.OptimumPageWeight / 2; } if (IsFormPaginationAllowed()) { if ((Paginate) || (ControlToPaginate == this)) { ControlPager pager = new ControlPager(this, pageWeight); base.PaginateRecursive(pager); return pager.PageCount; } else if(ControlToPaginate != null) { ControlPager pager = new ControlPager(this, pageWeight); SetControlPage(1); Control control = ControlToPaginate; MobileControl ctp = control as MobileControl; if(ctp != null) { ctp.PaginateRecursive(pager); } else { int firstAssignedPage = -1; DoPaginateChildren(pager, control, ref firstAssignedPage); } while(control != this) { MobileControl mc = control as MobileControl; if(mc != null) { if(mc is Form) { throw(new Exception(SR.GetString(SR.Form_InvalidControlToPaginateForm))); } if (mc.FirstPage > ctp.FirstPage) { mc.FirstPage = ctp.FirstPage; } if(mc.LastPage < ctp.LastPage) { mc.LastPage = ctp.LastPage; } } control = control.Parent; } this.LastPage = Math.Max(pager.PageCount, 1); if(Header != null) { SetEnablePaginationRecursive(Header, false); } if(Footer != null) { SetEnablePaginationRecursive(Footer, false); } return this.LastPage; } } return 1; } private bool IsFormPaginationAllowed() { // AUI 4721 if (Action.Length == 0) { return true; } MobileCapabilities device = (MobileCapabilities)Page.Request.Browser; String type = device.PreferredRenderingType; bool javascriptSupported = device.JavaScript; return javascriptSupported || (type != MobileCapabilities.PreferredRenderingTypeHtml32 && type != MobileCapabilities.PreferredRenderingTypeChtml10); } /// public override void PaginateRecursive(ControlPager pager) { _pageCount = PaginateForm(); } /// protected override bool PaginateChildren { get { return true; } } private Control _controlToPaginate = null; /// [ Bindable(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public Control ControlToPaginate { get { if(_controlToPaginate != null) { return _controlToPaginate; } if(ViewState["ControlToPaginate"] != null) { _controlToPaginate = Page.FindControl((ViewState["ControlToPaginate"]).ToString()); } return _controlToPaginate; } set { if(value != null) { ViewState["ControlToPaginate"] = value.UniqueID; } else { ViewState.Remove("ControlToPaginate"); } _controlToPaginate = value; } } /// protected override void LoadPrivateViewState(Object state) { _currentPage = state != null ? (int)state : 1; } /// protected override Object SavePrivateViewState() { int currentPage = _currentPage; if (currentPage > 1 && this == MobilePage.ActiveForm) { return currentPage; } else { return null; } } /// protected override void OnDataBinding(EventArgs e) { if(Script != null) { Script.DataBind(); } base.OnDataBinding(e); } private IPostBackEventHandler _defaultEventHandler = null; internal void RegisterEventHandler(IPostBackEventHandler control) { if (_defaultEventHandler == null) { _defaultEventHandler = control; } } internal IPostBackEventHandler DefaultEventHandler { get { return _defaultEventHandler; } } internal override void InvalidateParentStyles() { PagerStyle.InvalidateParentStyle(); base.InvalidateParentStyles(); } #region IPostBackEventHandler implementation void IPostBackEventHandler.RaisePostBackEvent(String eventArgument) { RaisePostBackEvent(eventArgument); } #endregion } /// [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] public class FormControlBuilder : LiteralTextContainerControlBuilder { /// public override void AppendSubBuilder(ControlBuilder subBuilder) { Type controlType = subBuilder.ControlType; if(!( (subBuilder.GetType().FullName == "System.Web.UI.CodeBlockBuilder") || (typeof(MobileControl).IsAssignableFrom(controlType)) || (typeof(UserControl).IsAssignableFrom(controlType)) || (typeof(DeviceSpecific).IsAssignableFrom(controlType)) )) { throw(new Exception(SR.GetString(SR.Form_InvalidSubControlType, subBuilder.TagName))); } base.AppendSubBuilder(subBuilder); } } }