///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DHTML Timer Custom Control (c) 2005 Manuel Abadia
//
// You are allowed to use this component in non commercial projects as long as you don't remove this copyright
// message from the source code of your project.
//
// For commercial projects, contact me: dotnetmanu@yahoo.com
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Flanders.Componentes
{
/// <summary>Control que representa un cron�metro que se muestra en el navegador del cliente mediante Javascript</summary>
/// <remarks>Creado por Manu el 14/02/2005</remarks>
[Designer(typeof(CronometroDesigner), typeof(IDesigner))]
[DefaultEvent("TimeOut"), DefaultProperty("Duracion")]
[System.Drawing.ToolboxBitmap(typeof(Cronometro), "cronometro.ico")]
public class Cronometro : WebControl, INamingContainer, IPostBackEventHandler
{
#region Campos
private static readonly object EventTimeOut = new object();
private Image _imgHora1;
private Image _imgHora0;
private Image _imgMin1;
private Image _imgMin0;
private Image _imgSeg1;
private Image _imgSeg0;
private DateTime _initialLoadTime;
#endregion
#region Propiedades
/// <summary>Devuelve el instante inicial de tiempo del servidor en el que se inici� el cron�metro</summary>
[Browsable(false)]
public DateTime InitialTime {
get {
object o = ViewState["InitialTime"];
if (o == null){
ViewState["InitialTime"] = DateTime.Now;
o = ViewState["InitialTime"];
}
return (DateTime)o;
}
set { ViewState["InitialTime"] = value; }
}
/// <summary>Devuelve el instante en el que el servidor inicia el cron�metro en este roundtrip</summary>
[Browsable(false)]
protected DateTime InitialLoadTime {
get {
if (_initialLoadTime == DateTime.MinValue){
_initialLoadTime = DateTime.Now;
}
return _initialLoadTime;
}
}
/// <summary>Ruta desde donde cargar el script</summary>
[Category("Behavior"), Description("Ruta desde donde cargar el script"), DefaultValue("")]
public string ScriptPath {
get {
string s = (string)ViewState["ScriptPath"];
if (s != null){
return s;
}
return String.Empty;
}
set { ViewState["ScriptPath"] = value; }
}
/// <summary>Ruta desde donde cargar las im�genes</summary>
[Category("Behavior"), Description("Ruta desde donde cargar las im�genes"), DefaultValue("")]
public string ImagesPath {
get {
string s = (string)ViewState["ImagesPath"];
if (s != null){
return s;
}
return String.Empty;
}
set { ViewState["ImagesPath"] = value; }
}
/// <summary>Estilo del cron�metro</summary>
[Editor(typeof(EstiloCronometroEditor), typeof(System.Drawing.Design.UITypeEditor))]
[Bindable(true), Category("Appearance"), Description("Estilo del cron�metro"), DefaultValue(typeof(EstiloCronometro), "fancyb")]
public EstiloCronometro Estilo {
get {
object o = ViewState["Estilo"];
if (o != null){
return (EstiloCronometro)o;
}
return EstiloCronometro.Fancy;
}
set { ViewState["Estilo"] = value; }
}
/// <summary>Indica la duraci�n del cron�metro</summary>
[Bindable(true), Category("Behavior"), Description("Indica la duraci�n del cron�metro"), DefaultValue(typeof(TimeSpan), "00:15:00")]
public TimeSpan Duracion {
get {
object o = ViewState["Duracion"];
if (o != null){
return (TimeSpan)o;
}
return new TimeSpan(0, 15, 0);
}
set { ViewState["Duracion"] = value; }
}
/// <summary>Indica si el contador es ascendente o descendente</summary>
[Category("Behavior"), Description("Indica si el contador es ascendente o descendente"), DefaultValue(true)]
public bool Ascendente {
get {
object o = ViewState["Ascendente"];
if (o != null){
return (bool)o;
}
return true;
}
set { ViewState["Ascendente"] = value; }
}
/// <summary>Indica si despu�s de que termine el contador se produce un evento de postback</summary>
[Category("Behavior"), Description("Indica si despu�s de que termine el contador se produce un evento de postback"), DefaultValue(true)]
public bool CausaPostBack {
get {
object o = ViewState["PostBack"];
if (o != null){
return (bool)o;
}
return true;
}
set { ViewState["PostBack"] = value; }
}
/// <summary>Mensaje a mostrar al terminarse el contador</summary>
[Category("Behavior"), Description("Mensaje a mostrar al terminarse el contador"), DefaultValue("Se ha agotado el tiempo.")]
public string Mensaje{
get {
string s = (string)ViewState["Mensaje"];
if (s != null){
return s;
}
return "Se ha agotado el tiempo.";
}
set { ViewState["Mensaje"] = value; }
}
/// <summary>Clase CSS que se usa para mostrar el mensaje</summary>
[Category("Appearance"), Description("Clase CSS que se usa para mostrar el mensaje"), DefaultValue("")]
public string MsgCssClass {
get {
string s = (string)ViewState["MsgCssClass"];
if (s != null){
return s;
}
return String.Empty;
}
set { ViewState["MsgCssClass"] = value; }
}
/// <summary>Se asegura de que est�n creados los controles hijos antes de acceder a la colecci�n de controles</summary>
public override ControlCollection Controls {
get {
EnsureChildControls();
return base.Controls;
}
}
#endregion
#region Eventos
[Category("Action"), Description("Evento producido al expirar el contador")]
public event EventHandler TimeOut {
add { Events.AddHandler(EventTimeOut, value); }
remove { Events.RemoveHandler(EventTimeOut, value); }
}
#endregion
#region Constructor
/// <summary>Constructor</summary>
public Cronometro()
{
_initialLoadTime = DateTime.MinValue;
}
#endregion
#region Creaci�n de los controles hijo
/// <summary>Crea los subcontroles que forman el control</summary>
protected override void CreateChildControls()
{
// limpia la colecci�n de controles
Controls.Clear();
// crea los controles hijo
_imgHora1 = new Image();
_imgHora0 = new Image();
_imgMin1 = new Image();
_imgMin0 = new Image();
_imgSeg1 = new Image();
_imgSeg0 = new Image();
// asigna un identificador a los controles hijo
_imgHora1.ID = "hora1";
_imgHora0.ID = "hora0";
_imgMin1.ID = "min1";
_imgMin0.ID = "min0";
_imgSeg1.ID = "seg1";
_imgSeg0.ID = "seg0";
// a�ade los controles hijo a la colecci�n de controles
Controls.Add(_imgHora1);
Controls.Add(_imgHora0);
Controls.Add(_imgMin1);
Controls.Add(_imgMin0);
Controls.Add(_imgSeg1);
Controls.Add(_imgSeg0);
}
#endregion
#region Creaci�n y registro del javascript del control
/// <summary>M�todo llamado antes de renderizar los controles y que se usa para registrar el javascript necesario</summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
// si est� activo, genera el javascript necesario
if (Enabled){
// si no est� registrado el script
if (!Page.IsStartupScriptRegistered("crono_tick")){
// registra la funci�n de inicio y la que actualiza el cron�metro
Page.RegisterClientScriptBlock("crono_tick", "<script language='javascript' src='" + base.ResolveUrl(ScriptPath) + "crono.js'></script>");
}
// si debe generar postback, registra la funci�n que genera el postback
if (CausaPostBack){
Page.RegisterClientScriptBlock(ClientID + ".postback",
@"<script language='javascript'>
function " + ClientID + @"_postBack(){
" + Page.GetPostBackEventReference(this) + @";
}
</script>"
);
}
// registra el script de incio
Page.RegisterStartupScript(ClientID + ".init",
@"<script language='javascript'>
var obj" + ClientID + @" = new Cronometro(
'" + ClientID + @"',
'" + Estilo.Nombre + @"',
" + HaExpirado().ToString().ToLower() + @",
" + Ascendente.ToString().ToLower() + @",
" + CausaPostBack.ToString().ToLower() + @",
'" + ResolveUrl(ImagesPath) + @"',
'" + Duracion.ToString() + @"',
" + InitialLoadTime.ToString("yyyy, ") + (InitialLoadTime.Month - 1).ToString("0") + InitialLoadTime.ToString(", d, H, m, s") + @"
);
</script>"
);
}
}
#endregion
#region Dibujo del control
/// <summary>Dibuja el control y los subcontroles en una tabla</summary>
/// <param name="writer">Escritor HTML a usar</param>
protected override void Render(HtmlTextWriter writer)
{
// si est� activo, renderiza el control
if (Enabled){
// escribe los atributos del control
AddAttributesToRender(writer);
// escribe la tabla con los controles hijo
writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_imgHora1.RenderControl(writer);
writer.RenderEndTag(); // Td
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_imgHora0.RenderControl(writer);
writer.RenderEndTag(); // Td
writer.AddAttribute(HtmlTextWriterAttribute.Valign, "center");
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(":");
writer.RenderEndTag(); // Td
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_imgMin1.RenderControl(writer);
writer.RenderEndTag(); // Td
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_imgMin0.RenderControl(writer);
writer.RenderEndTag(); // Td
writer.AddAttribute(HtmlTextWriterAttribute.Valign, "center");
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(":");
writer.RenderEndTag(); // Td
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_imgSeg1.RenderControl(writer);
writer.RenderEndTag(); // Td
writer.RenderBeginTag(HtmlTextWriterTag.Td);
_imgSeg0.RenderControl(writer);
writer.RenderEndTag(); // Td
writer.RenderEndTag(); // Tr
writer.RenderEndTag(); // Table
writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_text");
writer.AddAttribute(HtmlTextWriterAttribute.Style, "display:''");
writer.AddAttribute(HtmlTextWriterAttribute.Class, MsgCssClass);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(Mensaje);
writer.RenderEndTag(); // Td
writer.RenderEndTag(); // Tr
writer.RenderEndTag(); // Table
writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden");
writer.AddAttribute(HtmlTextWriterAttribute.Value, InitialTime.ToString("yyyyMMdd/HHmmss"));
writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID + "_initialTime");
writer.RenderBeginTag(HtmlTextWriterTag.Input);
writer.RenderEndTag(); // Input
}
}
#endregion
#region M�todos de la interfaz IPostBackEventHandler
public void RaisePostBackEvent(string eventArgument)
{
OnTimeOut(EventArgs.Empty);
}
#endregion
#region M�todos de ayuda
/// <summary>m�todo que produce un evento</summary>
/// <param name="e">par�metro del evento</param>
protected virtual void OnTimeOut(EventArgs e)
{
// obtiene el evento y llama a los delegados
EventHandler timeOutHandler = (EventHandler)Events[EventTimeOut];
if (timeOutHandler != null){
timeOutHandler(this, e);
}
}
/// <summary>indica si ha expirado el contador</summary>
/// <returns>true si ya ha expirado el contador</returns>
protected bool HaExpirado()
{
return DateTime.Now >= (InitialTime + Duracion);
}
#endregion
}
}