VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 626|回复: 9

关于控件事件流程

[复制链接]

1

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
发表于 2020-1-24 23:40:02 | 显示全部楼层 |阅读模式
代码如下:
using System;
using System.Collections.Specialized;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace 购物车
{
        /// <summary>
        /// WebCustomControl1 的摘要说明。
        /// </summary>
        public enum LoaderType{DetailLoader,CartLoader};
        public delegate void CartLoaderEventHandler(object sender,CartLoaderEventArgs e);

        public class CartLoaderEventArgs:EventArgs
        {
                private int _itemCount;
                private string _productNumber;
               
                public CartLoaderEventArgs(){}

                public CartLoaderEventArgs(string ProductNumber)
                {
                        _itemCount = 0;
                        _productNumber = ProductNumber;
                }

                public CartLoaderEventArgs(string ProductNumber,int NumberOfItems)
                {
                        _itemCount = NumberOfItems;
                        _productNumber = ProductNumber;
                }

                public string ProductNumber
                {
                        get{return _productNumber;}
                        set{_productNumber = value;}
                }

                public int NumberOfItems
                {
                        get{return _itemCount;}
                        set{_itemCount = value;}
                }

        }

        public class CartLoader : System.Web.UI.WebControls.WebControl,IPostBackDataHandler,IPostBackEventHandler
        {
                public event CartLoaderEventHandler ItemAdded;
                public event CartLoaderEventHandler ItemUpdated;
                public event CartLoaderEventHandler ItemRemoved;

                private LoaderType _location = LoaderType.DetailLoader;
                private string _productID;
                private int _itemCount;

                public LoaderType Location
                {
                        get{return _location;}
                        set{_location = value;}
                }
                public string ProductID
                {
                        get{return _productID;}
                        set{_productID = value;}
                }

                public int ItemCount
                {
                        get{return _itemCount;}
                        set{_itemCount = value;}
                }

                protected void OnItemAdded()
                {
                        if(ItemAdded != null)
                                ItemAdded(this,new CartLoaderEventArgs(_productID,_itemCount));
                }

                protected void OnItemUpdated()
                {
                        if (ItemUpdated != null)
                                ItemUpdated(this,new CartLoaderEventArgs(_productID,_itemCount));
                }

                protected void OnItemRemoved()
                {
                        if (ItemRemoved != null)
                                ItemRemoved(this,new CartLoaderEventArgs(_productID));
                }
                //加载文本框数据时引发
                public bool LoadPostData(string postDataKey,NameValueCollection postData)
                {
                        int count = Int32.Parse(postData[postDataKey]);
                        if (_itemCount != count)
                        {
                                _itemCount = count;
                                return true;
                        }
                        else
                        {
                                return false;
                        }
                }
                //如果控件启动回送.也就是有一个按钮被单击.调用此方法
                public void RaisePostDataChangedEvent()
                {
                        OnItemUpdated();
                }

                public void RaisePostBackEvent(string eventArgument)
                {
                        if (eventArgument == "AddToCart")
                        {
                                OnItemAdded();
                                _itemCount++;
                        }
                        else if(eventArgument == "RemoveFromCart")
                        {
                                OnItemRemoved();
                                _itemCount = 0;
                        }
                }

                protected override void Render(HtmlTextWriter output)
                {
                        //如果控件处在详细说明模式,呈现一个按钮把它添加到购物车中
                        if (_location == LoaderType.DetailLoader)
                        {
                                output.AddAttribute(HtmlTextWriterAttribute.Onclick,Page.GetPostBackEventReference(this,"AddToCart"));
                                output.AddAttribute(HtmlTextWriterAttribute.Style,"Display:inline;BORDER-RIGHT:gray thin outset;BORDER-TOP:gray thin outset;BORDER-LEFT:gray thin outset;CURSOR:hand;BORDER-BOTTOM:gray thin outset;FONT-FAMILY:'ComicSans MS';BACKGROUND-COLOR:lightgrey");
                                output.RenderBeginTag(HtmlTextWriterTag.Div);
                                output.Write("Add to cart");
                                output.RenderEndTag();
                        }
                        else//现在在购物车详细说明页面,因此显示两个按钮和一个文本框
                        {
                                output.AddAttribute(HtmlTextWriterAttribute.Width,"5");
                                output.AddAttribute(HtmlTextWriterAttribute.Name,this.UniqueID);
                                output.AddAttribute(HtmlTextWriterAttribute.Value,_itemCount.ToString());
                                output.RenderBeginTag(HtmlTextWriterTag.Input);
                                output.RenderEndTag();

                                //呈现删除按钮
                                output.AddAttribute(HtmlTextWriterAttribute.Style,"Display:inline;BORDER-RIGHT:gray thin outset;BORDER-TOP:gray thin outset;BORDER-LEFT:gray thin outset;CURSOR:hand;BORDER-BOTTOM:gray thin outset;FONT-FAMILY:'ComicSans MS';BACKGROUND-COLOR:lightgrey");
                                output.AddAttribute(HtmlTextWriterAttribute.Onclick,Page.GetPostBackEventReference(this,"RemoveFromCart"));
                                output.RenderBeginTag(HtmlTextWriterTag.Div);
                                output.Write("Remove");
                                output.RenderEndTag();

                                //呈现更新按钮
                                output.AddAttribute(HtmlTextWriterAttribute.Style,"Display:inline;BORDER-RIGHT:gray thin outset;BORDER-TOP:gray thin outset;BORDER-LEFT:gray thin outset;CURSOR:hand;BORDER-BOTTOM:gray thin outset;FONT-FAMILY:'ComicSans MS';BACKGROUND-COLOR:lightgrey");
                                output.AddAttribute(HtmlTextWriterAttribute.Onclick,Page.GetPostBackEventReference(this,""));
                                output.RenderBeginTag(HtmlTextWriterTag.Div);
                                output.Write("Update");
                                output.RenderEndTag();
                        }
                }

                protected override object SaveViewState()
                {
                        return (object)_itemCount;
                }

                protected override void LoadViewState(object state)
                {
                        _itemCount = (int)state;
                }


        }
}

当点击Add to Cart,Remove,Update会引发
LoadPostData(string postDataKey,NameValueCollection postData)方法
会进行判断原始数量是否用户刚输入数量是否相同.如果不同的话返回真.执行下列方法
public void RaisePostBackEvent(string eventArgument)
                {
                        if (eventArgument == "AddToCart")
                        {
                                OnItemAdded();
                                _itemCount++;
                        }
                        else if(eventArgument == "RemoveFromCart")
                        {
                                OnItemRemoved();
                                _itemCount = 0;
                        }
                }

但此方法
public void RaisePostDataChangedEvent()
                {
                        OnItemUpdated();
                }
当单击Update首先执行LoadPostData方法.会判断文本框内原始值是否等于用户输入的值.如果等于的话返回假.不会执行RaisePostBackEvent方法.而是执行
public void RaisePostDataChangedEvent()
                {
                        OnItemUpdated();
                }

这个方法.不知小弟理解的正确不正确.只是心里有点疑惑.或着哪位耐心看完这段程序后.给我讲一个完整的流程.THANK YOU
回复

使用道具 举报

0

主题

41

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-2-13 15:00:02 | 显示全部楼层
你说的是关于控件的生命周期
------------------
在生命周期中将执行一系列处理步骤,这些步骤包括:
实例化(Instantiate)
控件被页面或另一个控件通过调用它的构造器所实例化。这个步骤之后所列出的阶段,仅当控件加入控件树中才会发生。
初始化(Initialize)
初始化在传入 Web 请求生命周期内所需的设置。在此阶段,控件树中的页面和全部控件通过默认方式来调用OnInit方法。开发人员可以通过重载OnInit方法,为控件提供初始化逻辑。在其生命周期的这个时候,控件能够安全地访问其置于Controls集合中的子控件,但是它不能访问控件层次中的父控件或其他层次更高的控件(如页面)

开始跟踪视图状态(Begin Tracking View State)
这个阶段发生在初始化阶段的末尾。在此阶段页面自动调用TrackViewState方法。TrackViewState方法保证在此阶段之后,使用ViewState字典属性而产生的变化保存在控件视图状态中。在大多数情况下,Control基类提供的TrackViewState方法实现已经足够了,只有在控件定义了复杂属性时,才必须重载TrackViewState方法。

加载视图状态(仅用于回传过程)(Load View State (postback only))
这个阶段发生在回传时,而不是初始请求过程中,在此阶段结束时,就会自动填充控件的 ViewState 属性控件可以重写 LoadViewState 方法的默认实现,以自定义状态还原。

加载回传数据(仅用于回传过程,为可选项)(Load Postback Data(postback only, optional))
只有在控件通过实现IPostBackDataHandler接口参与了回传数据处理时,这个阶段才发生在回传中。TextBox控件就是一个例子。在这个阶段中,控件必须从已发送的表单数据中,通过实现IPostBackDataHandler借口的LoadPostData方法更新其状态。

加载(Load)
直到此阶段开始,控件树中的所有控件都已被初始化,并恢复到它们在先前周期最后的状态。OnLoad方法会执行所有请求共有的操作,如设置数据库查询。此时,树中的服务器控件已创建并初始化、状态已还原并且窗体控件反映了客户端的数据。如果需要实现仅在页面初始请求中执行的逻辑,那么实现该逻辑时,应该检查页面的IsPostBack属性

引发修改事件(仅用于回传过程,为可选项)(Raise Changed Events(postback only, optional))
只有在控件通过实现IPostBackDataHandler接口参与了回传数据处理时,这个阶段才发生在回传中。在此阶段中,控件通过引发事件(如TextBox的TextChanged事件)作为一种信号-----其状态由于回传而改变(引发更改事件以响应当前和以前回发之间的状态更改)。为了参与此阶段,控件必须实现IPostBackDataHandler接口的RaisePostDataChangedEvent方法。

引发回传事件(仅用于回传过程,为可选项)(Raise Postback Events(postback only, optional))
只有在控件通过实现IPostBackEventHandler接口参与了回传数据处理时,这个阶段才发生在回传中。在此阶段可以通过实现IPostBackEventHandler接口的RaisePostBackEvent方法来实现逻辑,以便把客户端事件映射到服务器端事件。

预生成(PreRender)
在此阶段中,应该通过重载OnPreRender方法,执行在生成控件之前所需要的任何工作。在生成输出之前执行任何更新,可以保存在预生成阶段对控件状态所做的更改,而在生成阶段所对应的更改则会丢失。

保存视图状态(Save View State)
如果控件不维持状态,或者它为保存其所有状态信息而使用ViewState字典,那么不必在此阶段期间实现任何附加逻辑。在此阶段期间,页面框架会自动保存ViewState字典。如果需要自定义状态管理,必须通过重载SaveViewState方法来实现自定义状态恢复,这种方法只被EnableViewState属性为true的控件所调用。在此阶段以后任何控件的改变都不会保存在控件的视图状态中。

生成(Render)
通过这种方法,控件在输出流上通过重载Control的Render方法或WebControl类的rendering方法中的一种,来写标记文本。

卸载(Unload)
在此阶段中,页面通过实现Page_Unload方法,来执行清除工作。作为控件开发者,应该重载Dispose方法来执行清除。

释放(Dispose)
在此阶段,应该重载Dispose方法来释放控件所占的全部资源。
回复

使用道具 举报

1

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
 楼主| 发表于 2020-2-13 18:30:01 | 显示全部楼层
我调试了一 遍.发现不论此方法返回真假.

                public bool LoadPostData(string postDataKey,NameValueCollection postData)
                {
                        int count = Int32.Parse(postData[postDataKey]);
                        if (_itemCount != count)
                        {
                                _itemCount = count;
                                return true;
                        }
                        else
                        {
                                return false;
                        }
                }
总是会执行
public void RaisePostBackEvent(string eventArgument)
                {
                        if (eventArgument == "AddToCart")
                        {
                                OnItemAdded();
                                _itemCount++;
                        }
                        else if(eventArgument == "RemoveFromCart")
                        {
                                OnItemRemoved();
                                _itemCount = 0;
                        }
                }
 这个方法.文档上说.当返回假的时候不会执行此方法.有点晕了.
回复

使用道具 举报

0

主题

41

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-2-13 23:45:01 | 显示全部楼层
返回 false 下面的不会执行了
public void RaisePostDataChangedEvent()
                {
                        OnItemUpdated();
                }

               
回复

使用道具 举报

0

主题

41

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-2-14 09:15:01 | 显示全部楼层
RaisePostBackEvent 是判断你是否回发,如果是回发都会执行它
回复

使用道具 举报

0

主题

41

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-2-14 10:45:01 | 显示全部楼层
public void RaisePostBackEvent(string eventArgument)
                {
//一般我们都在这里面做一些事件的委托处理
                       
                }
回复

使用道具 举报

1

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
 楼主| 发表于 2020-3-10 10:00:01 | 显示全部楼层
RaisePostBackEvent 是判断你是否回发,如果是回发都会执行它
??那到底当
public bool LoadPostData(string postDataKey,NameValueCollection postData)
返回假。是执行还是不执行呢?昨天调试的时候无论怎么回发都会执行RaisePostBackEvent
回复

使用道具 举报

0

主题

41

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-3-10 21:45:02 | 显示全部楼层
LoadPostData



RaisePostBackEvent 没有任何关系

它的返回值只能代表RaisePostDataChangedEvent 的执行和不执行
如果LoadPostData 返回 TRUE RaisePostDataChangedEvent 执行
如果LoadPostData 返回 false RaisePostDataChangedEvent 不执行
回复

使用道具 举报

0

主题

41

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-3-24 21:45:01 | 显示全部楼层
ASP.NET服务器控件与组件开发 -->学学基础
多练习一些自定义控件.
回复

使用道具 举报

1

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
 楼主| 发表于 2020-3-25 01:45:01 | 显示全部楼层
嗯。现在是在学。刚接触。所以蛮多不是蛮明白。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表