|
#region Copyright
/*
Copyright (C) 2005 Argiris Kirtzidis
This script is supplied "as is" without any form of warranty. I shall not be liable for
any loss or damage to person or property as a result of using this script. Use this script
at your own risk! You are licensed to use this script free of charge for commercial or
non-commercial use providing you do not remove the copyright notice or disclaimer.
*/
#endregion
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace Ajax.Controls
{
#region Public Class RenderStartEventArgs
/// <summary>
/// It contains the HtmlTextWriter writer event argument to be used during a
/// RenderStart event.
/// </summary>
public class RenderStartEventArgs : EventArgs
{
private bool abortRendering = false;
private HtmlTextWriter writer;
public bool AbortRendering
{
get { return abortRendering; }
set { abortRendering = value; }
}
public HtmlTextWriter Writer
{
get { return writer; }
}
public RenderStartEventArgs(HtmlTextWriter writer)
{
this.writer = writer;
}
}
#endregion
/// <summary>
/// The event handler for a RenderStart event.
/// </summary>
public delegate void RenderStartEventHandler(object sender, RenderStartEventArgs e);
/// <summary>
/// This control manages its appearance on the page using javascript that sends
/// to the client during a CallBack.
/// </summary>
/// <remarks>
/// It provides the basic functionality for controls like AjaxPanel. It manages
/// its tag attributes using javascript.
/// </remarks>
public class RenderedByScriptControl : AjaxControl, IPreRenderByScriptEventHandler, IRenderedByScript
{
private bool isRenderedOnPage = false;
private bool monitorVisibilityState = true;
private string currentTagHtml = null;
private string tagOnPageHtml = null;
private bool isHtmlRendered = false;
public event RenderStartEventHandler RenderStart;
public event EventHandler RenderEnd;
public event EventHandler PreRenderByScript;
// Disable EnableViewState so that the properties it sustains doesn't interfere with
// the funtionality provided by RenderedByScriptControl.
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override bool EnableViewState
{
get { return false; }
set { }
}
public override bool Visible
{
get
{
return base.Visible;
}
set
{
if ( CallBackHelper.IsCallBack
&& IsRenderedOnPage
&& MonitorVisibilityState
&& value != base.Visible )
CallBackHelper.WriteSetVisibilityOfElementScript (ClientID, value);
base.Visible = value;
}
}
/// <summary>
/// Determines whether the RenderedByScriptControl control has been rendered
/// on the page, either by normal rendering or by script.
/// </summary>
/// <remarks>
/// IsRenderedOnPage is set to true during a normal rendering or a rendering
/// by script. It is set to false only during a CallBackStartup.
/// </remarks>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsRenderedOnPage
{
get { return isRenderedOnPage; }
}
/// <summary>
/// Gets or sets whether every time "Visible" property is changed
/// CallBackHelper.WriteSetVisibilityOfElementScript method should be called.
/// Default is true.
/// </summary>
/// <remarks>
/// If this property is true, every time you change the "Visible" property during a
/// CallBack, the display attribute of the style of the control on the page will
/// be set to "" or "none" by calling the CallBackHelper.WriteSetVisibilityOfElementScript
/// method.
/// </remarks>
[Bindable(false), Category("Behavior"), DefaultValue(true)]
public bool MonitorVisibilityState
{
get { return monitorVisibilityState; }
set { monitorVisibilityState = value; }
}
/// <summary>
/// Returns the tag name of the control.
/// </summary>
/// <returns></returns>
public string GetTagName()
{
return TagKey.ToString();
}
public RenderedByScriptControl()
{
base.EnableViewState = false;
this.ID = "";
}
public RenderedByScriptControl(HtmlTextWriterTag tag) : base(tag)
{
base.EnableViewState = false;
this.ID = "";
}
/// <summary>
/// It defines whether the RenderedByScriptControl was already rendered during
/// a normal rendering.
/// </summary>
/// <remarks>
/// The RenderedByScriptControl can be normally rendered by the Render method
/// even during a CallBack (i.e when all the controls of an AjaxPanel is new
/// and the AjaxPanel renders all of them in a single html rendering).
/// In this case it's not necessary to send any javascript to the client.
/// </remarks>
protected bool IsHtmlRendered
{
get { return isHtmlRendered; }
}
protected override void OnCallBack(EventArgs e)
{
isHtmlRendered = false;
if ( CallBackHelper.IsCallBackStartup )
{
isRenderedOnPage = false;
currentTagHtml = tagOnPageHtml;
}
base.OnCallBack(e);
}
protected override void OnPreRender(EventArgs e)
{
CallBackHelper.RegisterCallBackStartupScript();
base.OnPreRender (e);
}
/// <summary>
/// Normal rendering.
/// </summary>
/// <remarks>
/// It raises the RenderStart and RenderEnd events. If the rendering is not
/// aborted during the RenderStart event, it renders the control and sets
/// the isHtmlRendered variable to true.
/// </remarks>
/// <param name="writer"></param>
protected override void Render(HtmlTextWriter writer)
{
RenderStartEventArgs eventArgs = new RenderStartEventArgs(writer);
OnRenderStart(eventArgs);
if (!eventArgs.AbortRendering)
{
base.Render (writer);
isHtmlRendered = true;
isRenderedOnPage = true;
}
OnRenderEnd(EventArgs.Empty);
}
/// <summary>
/// It stores the tag html for later checking.
/// </summary>
/// <param name="writer"></param>
public override void RenderBeginTag(HtmlTextWriter writer)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
HtmlTextWriter strwriter = new HtmlTextWriter(new System.IO.StringWriter(sb));
base.RenderBeginTag (strwriter);
tagOnPageHtml = currentTagHtml = sb.ToString();
base.RenderBeginTag (writer);
}
/// <summary>
/// Called by AjaxHttpModule
/// </summary>
public virtual void RaisePreRenderByScriptEvent()
{
OnPreRenderByScript (EventArgs.Empty);
}
/// <summary>
/// If the tag html of the control is changed, send the attributes using javascript.
/// </summary>
/// <returns>True if rendering by script was needed, False if it was not</returns>
public virtual bool RenderByScript()
{
// If there was a normal rendering, javascript is not needed
if (IsHtmlRendered)
return false;
if ( ! IsRenderedOnPage )
{
Control con = FindNextVisibleSibling();
CallBackHelper.WriteAddElementScript (Parent.ClientID, this.GetTagName(), this.ClientID, "", (con == null) ? null : con.ClientID);
}
System.Text.StringBuilder sb = new System.Text.StringBuilder();
HtmlTextWriter strwriter = new HtmlTextWriter(new System.IO.StringWriter(sb));
// Take care of the tag of the control
base.RenderBeginTag (strwriter);
string html = sb.ToString();
sb.Length = 0;
if(currentTagHtml != html)
{
CallBackHelper.WriteSetAttributesOfControl (ClientID, FormatAttributes(html));
currentTagHtml = html;
}
isRenderedOnPage = true;
return true;
}
protected virtual void OnRenderStart(RenderStartEventArgs eventArgs)
{
if (RenderStart != null)
RenderStart(this, eventArgs);
}
protected virtual void OnRenderEnd(EventArgs e)
{
if (RenderEnd != null)
RenderEnd(this, e);
}
protected virtual void OnPreRenderByScript(EventArgs e)
{
if (PreRenderByScript != null)
PreRenderByScript(this, e);
}
/// <summary>
/// Finds the next visible control of the control collection of this
/// control's parent that has its ID attribute set.
/// </summary>
/// <returns></returns>
private Control FindNextVisibleSibling()
{
for (int i=Parent.Controls.IndexOf(this) + 1; i < Parent.Controls.Count; i++)
{
Control con = Parent.Controls[i];
if (con.Visible && con.ID != null)
return con;
}
return null;
}
/// <summary>
/// It finds the attributes from the html of the control's tag, and formats them
/// so that they are send by CallBackHelper.WriteSetAttributesOfControl method.
/// </summary>
/// <param name="html">The html tag of the control</param>
/// <returns></returns>
private string FormatAttributes(string html)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(html);
System.Text.StringBuilder attribs = new System.Text.StringBuilder();
int mode = 0;
for (int i=0; i < sb.Length; i++)
{
char ch = sb[i];
if (ch == '>') break;
switch (mode)
{
case 0:
if (ch == ' ') mode++;
break;
case 1:
switch (ch)
{
case '\"':
mode++;
break;
case ' ':
attribs.Append ('|');
break;
default:
attribs.Append (ch);
break;
}
break;
case 2:
if (ch == '\"')
mode--;
else
attribs.Append (ch);
break;
}
}
return attribs.ToString();
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.