CompositeControls and RecreateChildControls()

Discussion in 'ASP .Net Building Controls' started by jeljeljel, Sep 20, 2007.

  1. jeljeljel

    jeljeljel Guest

    I have a CompositeControl (called SimplePager) that creates an
    UpdatePanel in its CreateChildControls override. The CompositeControl
    uses two LinkButtons to control the forward/backward state. W/out the
    use of the UpdatePanel it works just great. However, as a learning
    exercise I want to AJAXify the control. I am placing the entire
    control in an UpdatePanel. During the link click event handler, I
    make a call to RecreateChildControls() which throws an exception.

    This is so close to working. Can someone suggest how to accomplish
    what I am trying to do with an UpdatePanel?

    My class is copied below.

    Thanks,
    John


    public class SimplePager : CompositeControl
    {
    private int _currentRecord;
    private int _totalRecords;

    public SimplePager(int totalRecords)
    {
    _totalRecords = totalRecords;
    _currentRecord = 1;
    }

    protected override void OnInit(EventArgs e)
    {
    Page.RegisterRequiresControlState(this);

    EnsureChildControls();

    base.OnInit(e);
    }

    protected override void LoadControlState(object savedState)
    {
    int[] state;

    state = (int[])savedState;

    _currentRecord = state[0];
    _totalRecords = state[1];
    }

    protected override object SaveControlState()
    {
    int[] state;

    state = new int[] { _currentRecord, _totalRecords };

    return state;
    }

    protected override void CreateChildControls()
    {
    HtmlGenericControl div;
    LinkButton linkButton;
    UpdatePanel updatePanel;
    Label label;

    div = new HtmlGenericControl("div");
    Controls.Add(div);

    updatePanel = new UpdatePanel();
    updatePanel.ID = this.ID + "BWPagerUpdatePanel";
    updatePanel.ChildrenAsTriggers = true;
    updatePanel.UpdateMode =
    UpdatePanelUpdateMode.Conditional;
    div.Controls.Add(updatePanel);

    linkButton = new LinkButton();
    linkButton.Text = "<< prev";
    linkButton.ID = "prevPage";
    linkButton.Click += new EventHandler(linkButton_Click);

    updatePanel.ContentTemplateContainer.Controls.Add(linkButton);

    linkButton = new LinkButton();
    linkButton.Text = "next >>";
    linkButton.ID = "nextPage";
    linkButton.Click += new EventHandler(linkButton_Click);

    updatePanel.ContentTemplateContainer.Controls.Add(linkButton);

    label = new Label();
    label.ID = "SimplePagerTextBox";
    label.Text = String.Format("&nbsp;&nbsp;Page {0} of {1}",
    _currentRecord, _totalRecords);
    updatePanel.ContentTemplateContainer.Controls.Add(label);

    base.CreateChildControls();
    }

    private void linkButton_Click(object sender, EventArgs e)
    {
    LinkButton linkButton = sender as LinkButton;

    if (PageChange != null)
    {
    switch (linkButton.ID)
    {
    case "prevPage":
    if (_currentRecord > 1)
    _currentRecord--;
    break;

    case "nextPage":
    if (_currentRecord < _totalRecords)
    _currentRecord++;
    break;
    }

    PageChange(this, _currentRecord);

    RecreateChildControls();
    }
    }

    public int CurrentRecord
    {
    get
    {
    return _currentRecord;
    }
    }

    public delegate void PageChangeEvent(object sender, int
    newPage);
    public event PageChangeEvent PageChange;
    }
    jeljeljel, Sep 20, 2007
    #1
    1. Advertising

  2. I am not an expert with using UpdatePanels in CompositeControls, but I am
    wondering if the Control rendering process is getting confused somehow
    because of the fact that the Controls get added to
    updatePanel.ContentTemplateContainer.Controls rather than
    updatePanel.Controls? You may want to see if including the RenderContents()
    method helps (I don't know if it will or not, but it's worth a try).
    Something else I would like to point out, just as a suggestion, is that you
    are placing all of your controls into a div tag. There is nothing wrong with
    this, except that it is inefficient because the CompositeControl places all
    the rendered Controls into a div by default anyway. To control what tag
    everything is placed into and what attributes are added to that tag, use the
    following methods (note that my code is in VB.NET, but I'm sure you can do
    the necessary translation):

    Protected Overrides ReadOnly Property TagKey() As
    System.Web.UI.HtmlTextWriterTag
    'This method returns the tag that all rendered controls will be placed
    into
    Get
    Return HtmlTextWriterTag.Div
    End Get
    End Property

    Protected Overrides Sub AddAttributesToRender(ByVal writer As
    System.Web.UI.HtmlTextWriter)
    'Use this method to add attributes to the tag returned from the TagKey
    property
    writer.AddAttribute(HtmlTextWriterAttribute.Align, "left")
    MyBase.AddAttributesToRender(writer)
    End Sub

    If you view the output of your current code, you will see a div nested
    inside a div, if you use TagKey and AddAttributesToRender you will only see
    one. As for the UpdatePanel, I don't know if my suggestion will help, but it
    is good programming practice to implement it anyway. Good Luck!
    --
    Nathan Sokalski

    http://www.nathansokalski.com/

    "jeljeljel" <> wrote in message
    news:...
    >I have a CompositeControl (called SimplePager) that creates an
    > UpdatePanel in its CreateChildControls override. The CompositeControl
    > uses two LinkButtons to control the forward/backward state. W/out the
    > use of the UpdatePanel it works just great. However, as a learning
    > exercise I want to AJAXify the control. I am placing the entire
    > control in an UpdatePanel. During the link click event handler, I
    > make a call to RecreateChildControls() which throws an exception.
    >
    > This is so close to working. Can someone suggest how to accomplish
    > what I am trying to do with an UpdatePanel?
    >
    > My class is copied below.
    >
    > Thanks,
    > John
    >
    >
    > public class SimplePager : CompositeControl
    > {
    > private int _currentRecord;
    > private int _totalRecords;
    >
    > public SimplePager(int totalRecords)
    > {
    > _totalRecords = totalRecords;
    > _currentRecord = 1;
    > }
    >
    > protected override void OnInit(EventArgs e)
    > {
    > Page.RegisterRequiresControlState(this);
    >
    > EnsureChildControls();
    >
    > base.OnInit(e);
    > }
    >
    > protected override void LoadControlState(object savedState)
    > {
    > int[] state;
    >
    > state = (int[])savedState;
    >
    > _currentRecord = state[0];
    > _totalRecords = state[1];
    > }
    >
    > protected override object SaveControlState()
    > {
    > int[] state;
    >
    > state = new int[] { _currentRecord, _totalRecords };
    >
    > return state;
    > }
    >
    > protected override void CreateChildControls()
    > {
    > HtmlGenericControl div;
    > LinkButton linkButton;
    > UpdatePanel updatePanel;
    > Label label;
    >
    > div = new HtmlGenericControl("div");
    > Controls.Add(div);
    >
    > updatePanel = new UpdatePanel();
    > updatePanel.ID = this.ID + "BWPagerUpdatePanel";
    > updatePanel.ChildrenAsTriggers = true;
    > updatePanel.UpdateMode =
    > UpdatePanelUpdateMode.Conditional;
    > div.Controls.Add(updatePanel);
    >
    > linkButton = new LinkButton();
    > linkButton.Text = "<< prev";
    > linkButton.ID = "prevPage";
    > linkButton.Click += new EventHandler(linkButton_Click);
    >
    > updatePanel.ContentTemplateContainer.Controls.Add(linkButton);
    >
    > linkButton = new LinkButton();
    > linkButton.Text = "next >>";
    > linkButton.ID = "nextPage";
    > linkButton.Click += new EventHandler(linkButton_Click);
    >
    > updatePanel.ContentTemplateContainer.Controls.Add(linkButton);
    >
    > label = new Label();
    > label.ID = "SimplePagerTextBox";
    > label.Text = String.Format("&nbsp;&nbsp;Page {0} of {1}",
    > _currentRecord, _totalRecords);
    > updatePanel.ContentTemplateContainer.Controls.Add(label);
    >
    > base.CreateChildControls();
    > }
    >
    > private void linkButton_Click(object sender, EventArgs e)
    > {
    > LinkButton linkButton = sender as LinkButton;
    >
    > if (PageChange != null)
    > {
    > switch (linkButton.ID)
    > {
    > case "prevPage":
    > if (_currentRecord > 1)
    > _currentRecord--;
    > break;
    >
    > case "nextPage":
    > if (_currentRecord < _totalRecords)
    > _currentRecord++;
    > break;
    > }
    >
    > PageChange(this, _currentRecord);
    >
    > RecreateChildControls();
    > }
    > }
    >
    > public int CurrentRecord
    > {
    > get
    > {
    > return _currentRecord;
    > }
    > }
    >
    > public delegate void PageChangeEvent(object sender, int
    > newPage);
    > public event PageChangeEvent PageChange;
    > }
    >
    Nathan Sokalski, Sep 28, 2007
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=

    CompositeControls: ViewState properties w/ Mapped properties probl

    =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=, Jan 19, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    1,137
    Steven Cheng[MSFT]
    Jan 19, 2006
  2. Jeronimo Bertran

    CompositeControls not added to the toolbox

    Jeronimo Bertran, Apr 5, 2006, in forum: ASP .Net
    Replies:
    5
    Views:
    388
    Steven Cheng[MSFT]
    Apr 14, 2006
  3. Sky Sigal

    Immediate v. Delayed Delegation of Properties in CompositeControls

    Sky Sigal, Jun 29, 2005, in forum: ASP .Net Building Controls
    Replies:
    1
    Views:
    173
    Sky Sigal
    Jul 1, 2005
  4. jazzMan007

    Nested CompositeControls and page lifecycle

    jazzMan007, Nov 14, 2005, in forum: ASP .Net Building Controls
    Replies:
    0
    Views:
    164
    jazzMan007
    Nov 14, 2005
  5. jeljeljel

    UpdatePanel and RecreateChildControls

    jeljeljel, Sep 20, 2007, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    245
    Phil H
    Sep 22, 2007
Loading...

Share This Page