using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace WebControls.Test
{
public class PBLink:WebControl,IPostBackEventHandler
{
[Category("Behavior")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public string Text
{
get
{
object o = ViewState["Text"];
return o == null ? String.Empty : (string)o;
}
set { ViewState["Text"] = value; }
}
protected override void OnPreRender(EventArgs e)
{
if (Page != null)
Page.RegisterRequiresPostBack(this);
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter writer)
{
if (Page != null)
Page.VerifyRenderingInServerForm(this);
base.Render(writer);
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write(Text);
}
#region IPostBackEventHandler members
public void RaisePostBackEvent(string eventArgument)
{
throw new NotImplementedException();
}
#endregion
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.A;
}
}
}
}
运行后会报错:
“/WebSite”应用程序中的服务器错误。
只能对实现 IPostBackDataHandler 的控件调用 Page.RegisterRequiresPostBack。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.Web.HttpException: 只能对实现 IPostBackDataHandler 的控件调用 Page.RegisterRequiresPostBack。
源错误:
|
源文件: C:\MyProjects\csharp\test\controls\Controls\WebControls\Test\PBLink.cs 行: 29
至少说明
Page.RegisterRequiresPostBack 是和 IPostBackDataHandler 一起用的。
而
Page.RegisterRequiresRaiseEvent 一次只接受一个控件。
例如:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Collections.Specialized;
using System.ComponentModel;
namespace WebControls.BookSample
{
public class SimpleTextBoxTextChangedEventArgs : EventArgs
{
private string m_OldText;
private string m_NewText;
public SimpleTextBoxTextChangedEventArgs(string oldTxt, string newTxt)
{
m_OldText = oldTxt;
m_NewText = newTxt;
}
public string OldText
{
get { return m_OldText; }
}
public string NewText
{
get { return m_NewText; }
}
}
public delegate void SimpleTextBoxTextChange(object sender,SimpleTextBoxTextChangedEventArgs e);
public class SimpleTextBox:WebControl,IPostBackDataHandler,IPostBackEventHandler
{
private const string textKey = "Text";
private static readonly object textChangedKey = new object();
private static readonly object postBackKey = new object();
private string eventOldText;
private string eventNewText;
[Category("Action"), Description("This happens after changed!")]
public event SimpleTextBoxTextChange TextChanged
{
add { Events.AddHandler(textChangedKey, value); }
remove { Events.RemoveHandler(textChangedKey, value); }
}
protected void OnTextChanged(SimpleTextBoxTextChangedEventArgs e)
{
SimpleTextBoxTextChange handler = Events[textChangedKey] as SimpleTextBoxTextChange;
if (handler != null)
handler(this, e);
}
[Bindable(true), Category("Behavior"), DefaultValue(""), Description("text in textbox")]
public string Text
{
get
{
object o = ViewState[textKey];
return o == null ? String.Empty : (string)o;
}
set { ViewState[textKey] = value; }
}
[Category("Action"),Description("Nonsense")]
public event EventHandler PostBackEvent
{
add { Events.AddHandler(postBackKey, value); }
remove { Events.RemoveHandler(postBackKey, value); }
}
public void OnPostBackEvent(EventArgs e)
{
EventHandler handler = Events[postBackKey] as EventHandler;
if (handler != null)
handler(this, e);
}
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Input;
}
}
//protected override void OnPreRender(EventArgs e)
//{
// if (Page != null)
// Page.RegisterRequiresPostBack(this);
// base.OnPreRender(e);
//}
protected override void Render(HtmlTextWriter writer)
{
if (Page != null)
Page.VerifyRenderingInServerForm(this);
base.Render(writer);
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);
writer.AddAttribute(HtmlTextWriterAttribute.Value, Text);
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
}
#region IPostBackDataHandler members
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
eventOldText = Text;
eventNewText = postCollection[UniqueID];
bool hasChanged = (eventOldText != eventNewText);
Text = eventNewText;
Page.RegisterRequiresRaiseEvent(this);
return hasChanged;
}
public void RaisePostDataChangedEvent()
{
OnTextChanged(new SimpleTextBoxTextChangedEventArgs(eventOldText, eventNewText));
}
#endregion
#region IPostBackEventHandler members
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
OnPostBackEvent(EventArgs.Empty);
}
#endregion
}
}
当把SimpleTextBox一个以上数量的实例放置到页面上时,RaisePostBackEvent不执行,只有一个的时候却可以。
猜测并总结一下:
在一般情况下, IPostBackDataHandler 的方法由页面回传的Name去寻找控件并调用。当这种寻找并调用无法正常工作时,偏向于使用 Page.RegisterRequiresPostBack 将控件强行加入数据处理事件链中。
同样的,通常 IPostBackEventHandler 的方法由控件上的__doPostBack的脚本函数之类(这种函数多通过 Page.ClientScript.GetPostBackEventReference 和 Page.ClientScript.GetPostBackClientHyperlink来产生脚本调用代码)激发。 非正常情况可能就需要 Page.RegisterRequiresRaiseEvent的帮助
3226

被折叠的 条评论
为什么被折叠?



