动态添加自定义服务器控件中的PostBack触发器未正确呈现

时间:2010-11-24 16:20:43

标签: asp.net triggers updatepanel custom-controls viewstate

我正在构建一个源自CompositeControl的自定义服务器控件 该控件包含许多子控件(Labels,DropDownList,ListSearchExtender等)。所有这些都位于UpdatePanel内 该控件还发布事件。为此,我添加了两个属性:EnableCallBacks和CallBacksAsPostBacks。这两个属性应配置更新面板的回发行为。

任何想法正确的实现应该是什么样的?

我在实施它时遇到了一些问题:

  • PostBackTrigger并不总是呈现在输出html中。

  • Triggers.Add(trigger)方法中同时包含Controls.Add(_updatePanel)CreateChildControls会导致PostBackTrigger始终呈现,即使我稍后将其删除(例如在RenderControl()或PreRender中) ())。如果我不在这里添加触发器但稍后再添加触发器,那么它永远不会被渲染。在此阶段,我的所有属性都没有正确的值(例如EnableCallBacksCallBacksAsPostBacks)。

  • 不能将Controls.Add(_updatePanel)的语句放在RenderControl方法中,因为它对AJAX来说太晚了(最新的ist PreRender(),否则我得到一个例外)。

  • 理想情况下,我会在CreateChildControls()中实例化所有控件,然后在以下情况下设置它们的值。 PreRender或RenderControl

  • PreRender方法中导出两个语句,触发器会根据我在包含页面中的设置进行相应的呈现,但是我没有从ViewState中获取其数据的DropDownList (随叫随到/回发)。


protected override void CreateChildControls()
{
     base.CreateChildControls();
    _updatePanel = new UpdatePanel();
    _updatePanel.ID = "FprDropDownList_UpPnl";
    _updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;

    _label = new FprLabel();
    _label.ID = "FprDropDownList_Lbl";
    _updatePanel.ContentTemplateContainer.Controls.Add(_label);

    _dropDownList = new DropDownList();
    _dropDownList.ID = "FprDropDownList_Ddl";
    _dropDownList.CssClass = "fprDropDownList";
    _dropDownList.AutoPostBack = true;
    _updatePanel.ContentTemplateContainer.Controls.Add(_dropDownList);

    _label.AssociatedControlID = _dropDownList.ClientID;

    _listSearchExtender = new ListSearchExtender();
    _listSearchExtender.ID = "FprDropDownList_Lse";
    _listSearchExtender.TargetControlID = _dropDownList.ClientID;
    _listSearchExtender.PromptPosition = ListSearchPromtPosition;
    _listSearchExtender.PromptCssClass = "fprListSearchExtender";
    _updatePanel.ContentTemplateContainer.Controls.Add(_listSearchExtender);

    _ddlPostBackTrigger = new PostBackTrigger();
    _ddlPostBackTrigger.ControlID = _dropDownList.ClientID;

    //_updatePanel.Triggers.Add(_ddlPostBackTrigger);
    Controls.Add(_updatePanel);
}

protected override void OnPreRender(EventArgs pE)
{
   if (EnableCallBacks) 
   { 
      _dropDownList.SelectedIndexChanged += DropDownList_SelectedIndexChanged; 
   }
   if (EnableCallBacks && CallBacksAsPostBacks) 
   { 
     _updatePanel.Triggers.Add(_ddlPostBackTrigger); 
   }
   //Controls.Add(_updatePanel);
   base.OnPreRender(pE);
}

public override void RenderControl(HtmlTextWriter pWriter)
{
   // Do some things... like set Enable-state of child controls
   base.RenderControl(pWriter);
}

1 个答案:

答案 0 :(得分:0)

您应该在PreInit中添加动态控件,以便正确触发事件。

  

将此事件用于以下事项:

     
      
  • 检查IsPostBack属性   确定这是否是第一个   正在处理页面的时间。该   IsCallback和IsCrossPagePostBack
      此属性也已设定   时间。
  •   
  • 创建或重新创建动态   控制。
  •   
  • 设置母版页   动态。
  •   
  • 设置主题   属性动态。
  •   
  • 阅读或设置   个人资料属性值。
  •