No great solutions so I build my own. A pretty simple custom control. Comments welcome.
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace BinaryOcean.Web.Library.WebControls
{
[ToolboxData("<{0}:PostBackTimer runat=\"server\" />"), DefaultProperty("Seconds"), DefaultEvent("Timeout")]
public class PostBackTimer : Control, IPostBackEventHandler
{
public PostBackTimer() { }
public string CommandArgument
{
get { return (string)ViewState["CommandArgument"] ?? string.Empty; }
set { ViewState["CommandArgument"] = value; }
}
public string CommandName
{
get { return (string)ViewState["CommandName"] ?? string.Empty; }
set { ViewState["CommandName"] = value; }
}
public bool Enabled
{
get { return (bool)(ViewState["Enabled"] ?? true); }
set { ViewState["Enabled"] = value; }
}
public int Seconds
{
get { return (int)(ViewState["Seconds"] ?? 0); }
set { ViewState["Seconds"] = value; }
}
[Description("PostBackTimer_OnTimeout")]
public event EventHandler Timeout = delegate { };
[Description("PostBackTimer_OnCommand")]
public event CommandEventHandler Command = delegate { };
public void RaisePostBackEvent(string eventArgument)
{
Timeout(this, EventArgs.Empty);
Command(this, new CommandEventArgs(CommandName, CommandArgument));
}
protected override void OnPreRender(EventArgs e)
{
if (Enabled && Seconds > 0)
{
var postback = Page.ClientScript.GetPostBackEventReference(this, null);
var script = string.Format("setTimeout(\"{0}\",{1});", postback, Seconds * 1000);
Page.ClientScript.RegisterStartupScript(GetType(), "PostBackTimer_" + UniqueID, script, true);
}
base.OnPreRender(e);
}
}
}