IPostBackDataHandler & IPostBackEventHandler

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。

源错误:

 

行 27:         {
行 28:             if (Page != null)
行 29:                 Page.RegisterRequiresPostBack(this);
行 30:             base.OnPreRender(e);
行 31:         }

 


源文件: 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的帮助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值