locked
Click Event ReBind RRS feed

  • Question

  • User-573048658 posted

    I've created a test server control (below) to demonstrate the issue that I'm having, which I have pin-pointed with a TODO: token.

    Keep in mind, this is just a test control (for demonstration), I realize there is code optimization opportunities.  In addition, this was created with VS2008.

    That said, when adding a comment, the DataSource is successfully updated, however, the control is already rendered by the time the click event is fired.  Therefore, the updated DataSource will affect the rendered control only upon the next postback.

    So, for example:

    typed "Test1" and clicked [Add] ... No comment is presented by the control (but DataSource is correct)
    typed "Test2" and clicked [Add] ... "Test1" shows up (but DataSource holds "Test1" and "Test2")

    I was looking for a ReBind() or something along those lines.  Just as a note, I tried DataBind(), this doesn't work.

    Thank you in advance for any help you can bring.

    -Jessy Houle

     

    using System;
    using System.Collections.Generic;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace CommentsClassLibrary
    {
        public class AddCommentsControl : WebControl, INamingContainer
        {
            [Serializable]
            public struct CommentData
            {
                public string CommentText { get; set; }
            }
    
            protected Button AddButton;
            protected TextBox CommentTextBox;
    
            public List<COMMENTDATA> DataSource
            {
                get
                {
                    var dataSource = ViewState["DataSource"];
    
                    if (dataSource == null)
                        return new List<COMMENTDATA>();
    
                    return (List<COMMENTDATA>)dataSource;
                }
                set
                {
                    ViewState["DataSource"] = value;
                }
            }
    
            protected override void CreateChildControls()
            {
                AddButton = new Button { Text = "Add" };
                AddButton.Click += AddButton_Click;
                CommentTextBox = new TextBox();
    
                Controls.Add(AddButton);
                Controls.Add(CommentTextBox);
    
                if (DataSource.Count > 0)
                {
                    foreach (var commentData in DataSource)
                    {
                        var commentChild = new CommentControl { CommentText = commentData.CommentText };
                        Controls.Add(commentChild);
                    }
                }
            }
    
            protected override void RenderContents(HtmlTextWriter writer)
            {
                EnsureChildControls();
    
                CommentTextBox.RenderControl(writer);
                writer.WriteLine("&nbsp;   ");
                AddButton.RenderControl(writer);
    
                writer.WriteLine("&lt;BR><BR><BR>");
    
                foreach (Control c in Controls)
                {
                    if (c is CommentControl)
                        c.RenderControl(writer);
                }
            }
    
            void AddButton_Click(object sender, EventArgs e)
            {
                var commentData = new CommentData { CommentText = CommentTextBox.Text };
                var commentDataList = new List<COMMENTDATA>(DataSource) {commentData};
    
                DataSource = commentDataList;
    
                //TODO: rebind control, as DataSource has been updated
            }
    
            private class CommentControl : WebControl, INamingContainer
            {
                public string CommentText { get; set; }
    
                protected override void RenderContents(HtmlTextWriter writer)
                {
                    writer.WriteLine("Comment: " + CommentText + "&lt;BR>");
                }
            }
        }
    }
     
    Tuesday, July 29, 2008 1:39 PM

Answers

  • User-573048658 posted
    Got it!  A very weird workaround, but here is the code.

    I ended up adding an event to allow front-end (ASPX Page) hooks:

    public event EventHandler DataUpdated;


    I also added a ReRender property:

    public bool ReRender
    {
        get
        {
    	var reRender = ViewState["ReRender"];
    
    	if (reRender != null)
    	    return (bool)reRender;
    
    	return false;
        }
        set
        {
    	ViewState["ReRender"] = value;
        }
    }


    On the front-end (ASPX Page) within the event handler I set ReRender to true and call DataBind:

    GeneralComments.ReRender = true;
    GeneralComments.DataBind();


    ... which calls the RenderContents(), NOT the CreateChildControls(), which is what I was wishing for.  Within RenderContents() I added a conditional control re-creation:

    if(ReRender)
    {
    Controls.Clear();
    CreateChildControls();
    ReRender = false;
    }
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, July 29, 2008 4:30 PM