/* * Renders all controls that was added this request. */ void RenderAddedWidgets() { // Making sure all children rendered from this point are rendered as pure HTML. RenderMode = RenderingMode.ReRender; // Looping through all Controls, figuring out which were not there in the "_originalCollection", before it was changed, and retrieving their // HTML, such that we can pass it to the client, as a JSON insertion. foreach (var idx in Controls.Cast <Widget> ().Where(ix => !_originalCollection.Contains(ix) && !string.IsNullOrEmpty(ix.ID))) { // Getting control's HTML, by rendering it into a MemoryStream, and for then to pass it on as an "insertion" to our AjaxPage. using (var stream = new MemoryStream()) { using (var txt = new HtmlTextWriter(new StreamWriter(stream))) { idx.RenderControl(txt); txt.Flush(); } // Now we can read the HTML from our MemoryStream. stream.Seek(0, SeekOrigin.Begin); using (TextReader reader = new StreamReader(stream)) { // Registering currently iterated widget's HTML as an insertion on client side. AjaxPage.RegisterWidgetChanges(JsonClientID, "__p5_add_" + Controls.IndexOf(idx), reader.ReadToEnd()); } } } }
/* * Responsible for rendering all different permutations for a visible widget. */ void RenderVisibleWidget(HtmlTextWriter writer) { // How its ancestor Control(s) are being rendered, largely detremine how this widget is rendered, since an ancestor being shown, // that was previously hidden, or newly created for that matter, triggers a re-rendering of the entire widget, one way or another. if (!AjaxPage.IsAjaxRequest || AncestorIsReRendering()) { // Not an Ajax request, or ancestors are re-rendering widget somehow. // Hence, we default to rendering widget as HTML into the given HtmlTextWriter. RenderHtmlResponse(writer); } else if (RenderMode == RenderingMode.ReRender) { // Re-rendering entire widget, including its children. using (var streamWriter = new StreamWriter(new MemoryStream())) { using (var txt = new HtmlTextWriter(streamWriter)) { RenderHtmlResponse(txt); txt.Flush(); streamWriter.BaseStream.Seek(0, SeekOrigin.Begin); using (TextReader reader = new StreamReader(streamWriter.BaseStream)) { AjaxPage.RegisterWidgetChanges(JsonClientID, "outerHTML", reader.ReadToEnd()); } } } } else { // Only pass changes for this widget back to the client as JSON, before we render its children. Attributes.RegisterChanges(AjaxPage, JsonClientID); RenderChildren(writer); } }
/* * Renders all controls that was added this request. */ private void RenderAddedWidgets() { // Looping through all Controls, figuring out which were not there in the "_originalCollection", before it was changed, and retrieving their // HTML, such that we can pass it to the client, as a JSON insertion. for (var idxNo = 0; idxNo < Controls.Count; idxNo++) { var idx = Controls [idxNo]; if (_originalCollection.Contains(idx) || string.IsNullOrEmpty(idx.ID)) { continue; // Control has already been rendered, or is a literal control without an ID } // Getting control's HTML, by rendering it into a MemoryStream, and for then to pass it on as an "insertion" to our AjaxPage. using (var stream = new MemoryStream()) { using (var txt = new HtmlTextWriter(new StreamWriter(stream))) { idx.RenderControl(txt); txt.Flush(); } // Now we can read the HTML from our MemoryStream. stream.Seek(0, SeekOrigin.Begin); using (TextReader reader = new StreamReader(stream)) { // Registering currently iterated widget's HTML as an insertion on client side. AjaxPage.RegisterWidgetChanges(ClientID, "__p5_add_" + idxNo, reader.ReadToEnd()); } } } }
/// <summary> /// Renders the widget. /// /// Overridden to entirely bypass the ASP.NET Web Forms rendering, and provide our own with Ajax support. /// </summary> /// <param name="writer">Writer.</param> public override void RenderControl(HtmlTextWriter writer) { if (AreAncestorsVisible()) { var ancestorReRendering = IsAncestorReRenderingThisWidget(); if (Visible) { if (AjaxPage.IsAjaxRequest && !ancestorReRendering) { if (RenderMode == RenderingMode.ReRender) { // Re-rendering entire widget. // Notice, since GetWidgetHtml will return HTML for widget, and its children controls, it's not necessary to invoke // "RenderChildren" or any similar methods here. AjaxPage.RegisterWidgetChanges(_oldId ?? ClientID, "outerHTML", GetWidgetHtml()); } else if (RenderMode == RenderingMode.ChildrenCollectionModified) { // Re-rendering all children controls, but also renders changes to widget. _attributes.RegisterChanges(AjaxPage, _oldId ?? ClientID); RenderChildrenWidgetsAsJson(writer); } else { // Only pass changes back to client as JSON. _attributes.RegisterChanges(AjaxPage, _oldId ?? ClientID); RenderChildren(writer); } } else { // Not an Ajax request, or ancestors are re-rendering widget somehow. RenderHtmlResponse(writer); } } else { // Invisible widget. if (AjaxPage.IsAjaxRequest && RenderMode == RenderingMode.RenderInvisible && !ancestorReRendering) { // Re-rendering widget's invisible markup. // Widget was probably made invisible during the current request. AjaxPage.RegisterWidgetChanges(_oldId ?? ClientID, "outerHTML", GetWidgetInvisibleHtml()); } else if (!AjaxPage.IsAjaxRequest || ancestorReRendering) { // Rendering invisible HTML. writer.Write(GetWidgetInvisibleHtml()); } } } }
/* * Responsible for rendering all different permutations for an invisible widget. */ void RenderInvisibleWidget(HtmlTextWriter writer) { var ancestorReRendering = AncestorIsReRendering(); if (AjaxPage.IsAjaxRequest && RenderMode == RenderingMode.WidgetBecameInvisible && !ancestorReRendering) { // Re-rendering widget's invisible markup, since widget was made invisible during the current request. AjaxPage.RegisterWidgetChanges( JsonClientID, "outerHTML", string.Format(@"<{0} id=""{1}"" style=""display:none important!;""></{0}>", Element, ClientID)); } else if (!AjaxPage.IsAjaxRequest || ancestorReRendering) { // Rendering invisible HTML. writer.Write(string.Format(@"<{0} id=""{1}"" style=""display:none important!;""></{0}>", Element, ClientID)); } }
/// <summary> /// Registers the changed attributes during this request. /// </summary> /// <param name="page">The Ajax page that owns the current instance</param> /// <param name="id">ID of widget that owns storage object</param> internal void RegisterChanges(AjaxPage page, string id) { // Adding up the ones that were deleted during this request. foreach (var idx in _dynamicallyRemovedThisRequest) { page.RegisterDeletedAttribute(id, idx.Name); } // Adding up our changes. foreach (var idx in _dynamicallyAddedThisRequest) { // Checking if this is an invisible attribute, at which case it is never rendered back to client. if (idx.Name.StartsWith("_", StringComparison.InvariantCulture) || idx.Name.StartsWith(".", StringComparison.InvariantCulture)) { continue; } // Registering change to be returned to client. page.RegisterWidgetChanges(id, idx.Name, idx.Value); } }
/// <summary> /// Renders all children as JSON update(s) back to client. /// </summary> protected virtual void RenderChildrenWidgetsAsJson(HtmlTextWriter writer) { // re-rendering all children by default AjaxPage.RegisterWidgetChanges(ClientID, "innerValue", GetChildrenHtml()); }