PostBack2

  this._requestValueCollection = this.PageAdapter.DeterminePostBackMode();

1首先给 _requestValueCollection 赋值,值为 Request.Form

是一个Page页面上的input控件集合.

2

 

private void ProcessPostData(NameValueCollection postData, bool fBeforeLoad)
{
    
if (this._changedPostDataConsumers == null)
    {
        
this._changedPostDataConsumers = new ArrayList();
    }
    
if (postData != null)
    {
        
foreach (string str in postData)
        {
            
if ((str == null|| IsSystemPostField(str))
            {
                
continue;
            }
            Control control 
= this.FindControl(str);
            
if (control == null)
            {
                
if (fBeforeLoad)
                {
                    
if (this._leftoverPostData == null)
                    {
                        
this._leftoverPostData = new NameValueCollection();
                    }
                    
this._leftoverPostData.Add(str, null);
                }
                
continue;
            }
            IPostBackDataHandler postBackDataHandler 
= control.PostBackDataHandler;
            
if (postBackDataHandler == null)
            {
                
if (control.PostBackEventHandler != null)
                {
                    
this.RegisterRequiresRaiseEvent(control.PostBackEventHandler);
                }
            }
            
else
            {
                 //如果这些控件中有实现了IPostBackDataHandler 接口的,调用这个控件的LoadPostData方法.
                
if ((postBackDataHandler != null&& postBackDataHandler.LoadPostData(str, this._requestValueCollection))
                {
                    
this._changedPostDataConsumers.Add(control);
                }
                
if (this._controlsRequiringPostBack != null)
                {
                    
this._controlsRequiringPostBack.Remove(str);
                }
            }
        }
    }
    ArrayList list 
= null;
    
if (this._controlsRequiringPostBack != null)
    {
        
foreach (string str2 in this._controlsRequiringPostBack)
        {
            Control control2 
= this.FindControl(str2);
            
if (control2 != null)
            {
                IPostBackDataHandler handler2 
= control2._adapter as IPostBackDataHandler;
                
if (handler2 == null)
                {
                    handler2 
= control2 as IPostBackDataHandler;
                }
                
if (handler2 == null)
                {
                    
throw new HttpException(SR.GetString("Postback_ctrl_not_found"new object[] { str2 }));
                }
                //  这里是调用 ._controlsRequiringPostBack集合的LoadPostData()方法
                
if (handler2.LoadPostData(str2, this._requestValueCollection))
                {
                    
this._changedPostDataConsumers.Add(control2);
                }
                
continue;
            }
            
if (fBeforeLoad)
            {
                
if (list == null)
                {
                    list 
= new ArrayList();
                }
                list.Add(str2);
            }
        }
        
this._controlsRequiringPostBack = list;
    }
}

 ._controlsRequiringPostBack 什么时候这个集合中有值呢。当我们调用Page.RegisterRequiresPostBack ()这个方法的时候。
 
[EditorBrowsable(EditorBrowsableState.Advanced)]
public void RegisterRequiresPostBack(Control control)
{
    
if (!(control is IPostBackDataHandler) && !(control._adapter is IPostBackDataHandler))
    {
        
throw new HttpException(SR.GetString("Ctrl_not_data_handler"));
    }
    
if (this._registeredControlsThatRequirePostBack == null)
    {
        
this._registeredControlsThatRequirePostBack = new ArrayList();
    }
    
this._registeredControlsThatRequirePostBack.Add(control.UniqueID);
}
那么通过上面我们可以看出
在Render 控件的过程当中, 需要把控件的UniqueID 作为需要PostBackData 的Input 标签的name
属性。否则即使实现了IPostBackDataHandler 接口 LoadPostData 方法也不会执行. 
为什么不执行呢?因为 如果没有这个name的Input 标签,那么
IPostBackDataHandler postBackDataHandler = control.PostBackDataHandler;
这个执行为空,也就是说Request.Form中不会去加载我们实现了 IPostBackDataHandler
的自定义控件。
 
那如果有这么一个控件,那么它一定会被加载到Request.Form中去,这时候 当我们
执行     Control control2 = this.FindControl(str2);
  这个方法时候,得到我们自己的自定义控件。
 
 
如果LoadPostData()返回true
则调用  this._changedPostDataConsumers.Add(control2);
添加到这个list中
在Load后调用执行 RaisePostDataChangedEvent 事件,一直冒泡至自定义事件处理。
internal void RaiseChangedEvents()
{
    
if (this._changedPostDataConsumers != null)
    {
        
for (int i = 0; i < this._changedPostDataConsumers.Count; i++)
        {
            Control control 
= (Control) this._changedPostDataConsumers[i];
            
if (control != null)
            {
                IPostBackDataHandler postBackDataHandler 
= control.PostBackDataHandler;
                
if (((control == null|| control.IsDescendentOf(this)) && ((control != null&& (control.PostBackDataHandler != null)))
                {
                    postBackDataHandler.RaisePostDataChangedEvent();
                }
            }
        }
    }
}

 在调用完RaiseChangedEvents()后

继续调用

 

private void RaisePostBackEvent(NameValueCollection postData)
{
    
if (this._registeredControlThatRequireRaiseEvent != null)
    {
        
this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
    }
    
else
    {
        
string str = postData["__EVENTTARGET"]; //读取 _doPostBack()的第一个参数,
        
bool flag = !string.IsNullOrEmpty(str);
        
if (flag || (this.AutoPostBackControl != null))
        {
            Control control 
= null;
            
if (flag)
            {
                control 
= this.FindControl(str); //找到这个实现了IPostBackEventHandler控件
            }
            
if ((control != null&& (control.PostBackEventHandler != null))
            {
                
string eventArgument = postData["__EVENTARGUMENT"]; //读取 _doPostBack()的第二个参数
                
this.RaisePostBackEvent(control.PostBackEventHandler, eventArgument);//调用回发事件
            }
        }
        
else
        {
            
this.Validate();
        }
    }
}
 
这里我们可以看出有2种方法能够引发 PostBackEvent
1.registeredControlThatRequireRaiseEvent
 
[EditorBrowsable(EditorBrowsableState.Advanced)]
public virtual void RegisterRequiresRaiseEvent(IPostBackEventHandler control)
{
    
this._registeredControlThatRequireRaiseEvent = control;
}

 
通过调用 Page.RegisterRequiresRaiseEvent 来直接调用
this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
 
2

 

posted on 2011-04-06 19:44  kasafuma  阅读(193)  评论(0编辑  收藏  举报