Click here to Skip to main content
15,175,959 members
Please Sign up or sign in to vote.
3.00/5 (4 votes)
See more:
I want to add a user control within user control.
But, Child control is added to all the parent controls, while i am clicking on a button of a parent user control.I am writing my code below.Please suggest me.It's urgent.Main page's name is kept default.Parent user control is WebUserControl.ascx
and Child user control is payment.ascx.
Below is a code.

payment.ascx

XML
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="payment.ascx.cs" Inherits="Payment.payment" %>
<asp:Panel ID="Panel1" runat="server">

<asp:TextBox ID="txtpercentage" runat="server" Width="152px"></asp:TextBox>
    <asp:TextBox ID="txtdetails" runat="server" Width="152px"></asp:TextBox>
    <asp:Button ID="btndelete" runat="server" BackColor="Red" BorderColor="Red"
        CausesValidation="False" Height="20px" onclick="btndelete_Click"
        Text="Delete" />
    <br />
    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
        ControlToValidate="txtpercentage"
        ErrorMessage="Please Specify percentage of payment"></asp:RequiredFieldValidator>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
        ControlToValidate="txtdetails" ErrorMessage="Please Specify Payment Details"></asp:RequiredFieldValidator>
</asp:Panel>



payment.ascx.cs
C#
namespace Payment
{
    public partial class payment : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        public void disable()
        {
            txtdetails.Enabled = false;
            txtpercentage.Enabled = false;
            btndelete.Visible = false;
        }
        public string percentage
        {
            get
            {
                return txtpercentage.Text;
            }
            set
            {
                txtpercentage.Text = value;
            }
        }
        public string details
        {
            get
            {
                return txtdetails.Text;
            }
            set
            {
                txtdetails.Text = value;
            }
        }
        public void Sup_Disable()
        {
            btndelete.Enabled = false;
            txtdetails.Enabled = false;
            txtpercentage.Enabled = false;
        }
        public event EventHandler RemoveUserControl;

        protected void btndelete_Click(object sender, EventArgs e)
        {
            if (RemoveUserControl != null)
            {
                RemoveUserControl(sender, e);
            }
        }
    }
}


WebUserControl.ascx
XML
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="TryControl.WebUserControl" %>
<%@ Register src="payment.ascx" tagname="payment" tagprefix="uc1" %>

<table>
        <tr>
            <td>Textbox Example:</td>
            <td>
                <asp:TextBox ID="tbx1" runat="server" />
            </td>
        </tr>
        <tr>
            <td>Dropdown Example:</td>
            <td>
                <asp:DropDownList ID="ddl1" runat="server">
                    <asp:ListItem Text="Dropdown 1" />
                    <asp:ListItem Text="Dropdown 2" />
                    <asp:ListItem Text="Dropdown 3" />
                </asp:DropDownList>
            </td>
        </tr>
        <tr>
            <td>Checkbox Example:</td>
            <td>
                <asp:CheckBoxList ID="cbx1" runat="server">
                    <asp:ListItem Text="Checkbox 1" />
                    <asp:ListItem Text="Checkbox 2" />
                    <asp:ListItem Text="Checkbox 3" />
                </asp:CheckBoxList>
            </td>
        </tr>
    </table>

    <asp:Button ID="btnRemove" runat="server" Text="Remove"
    onclick="btnRemove_Click1" />

    <asp:Literal ID="ltlCount1" runat="server" Text="0"></asp:Literal>
<asp:Literal ID="ltlRemoved1" runat="server"></asp:Literal>
<br />
<asp:Button ID="btnadd1" runat="server" onclick="btnadd1_Click"
    style="width: 37px" Text="Add" CausesValidation="False" />

    <br />
<asp:PlaceHolder ID="ph2" runat="server"></asp:PlaceHolder>

    <hr />


WebUserControl.ascx.cs

C#
namespace TryControl
{
    public partial class WebUserControl : System.Web.UI.UserControl
    {
        payment p1;
        protected void Page_Load(object sender, EventArgs e)
        {
            
        }
        public void AddpayControl()
        {
           
            //System.Web.UI.WebControls.Button but = new System.Web.UI.WebControls.Button();
            //string d1 = ((WebUserControl)sender).ID.ToString();
            //ph1.Controls.Remove(DynamicUserControl1); //MessageBox.Show(Request.Params.ToString().IndexOf("btnadd1").ToString());
            if (Request.Params.ToString().IndexOf("btnadd1") &gt; 0)
            {
                ltlCount1.Text = (Convert.ToInt16(ltlCount1.Text) + 1).ToString();     
            }
            //Be sure everything in the placeholder control is cleared out
            ph2.Controls.Clear();
            int ControlID = 0;
            //Since these are dynamic user controls, re-add them every time the page loads.
            for (int i = 0; i &lt;= (Convert.ToInt16(ltlCount1.Text) - 1); i++)
            {
                p1 = (payment)LoadControl("payment.ascx");
                //If this particular control id has been deleted from the page, DO NOT use it again.  If we do, it will
                //pick up the viewstate data from the old item that had this control id, instead of generating
                //a completely new control.  Instead, increment the control id so we're guaranteed to get a "new"
                //control that doesn't have any lingering information in the viewstate.            
                while (InDeletedList("uc" + ControlID) == true)
                {
                    ControlID += 1;
                }
                //Note that if the item has not been deleted from the page, we DO want it to use the same control id
                //as it used before, so it will automatically maintain the viewstate information of the user control
                //for us.
                p1.ID = "uc1" + ControlID;
                //Add an event handler to this control to raise an event when the delete button is clicked
                //on the user control
                p1.RemoveUserControl += new EventHandler(HandleRemoveUserControl);
                //Finally, add the user control to the panel
                ph2.Controls.Add(p1);
                //Increment the control id for the next round through the loop
                ControlID += 1;
            }
        }
        private bool InDeletedList(string ControlID)
        {
            //Determine if the passed in user control id has been stored in the list of controls that
            //were previously deleted off the page
            string[] DeletedList = ltlRemoved1.Text.Split('|');
            for (int i = 0; i &lt;= DeletedList.GetLength(0) - 1; i++)
            {
                if (ControlID.ToLower() == DeletedList[i].ToLower())
                {
                    return true;
                }
            }
            return false;
        }
        public void HandleRemoveUserControl(object sender, EventArgs e)
        {
            //This handles delete event fired from the user control
            //Get the user control that fired this event, and remove it
            //WebUserControl DynamicUserControl = sender.Parent;
            //Button but = null;
            //Button but = new Button();
            //but = (Button)sender;
            System.Web.UI.WebControls.Button but = new System.Web.UI.WebControls.Button();
            but = (System.Web.UI.WebControls.Button)sender;
            //Response.Write(sender);
            //itemtypecategory Item = (itemtypecategory)sender;
            //itemsummary Item = (itemsummary)but.Parent.Parent;
            payment DynamicUserControl1 = (payment)but.Parent.Parent; ;
            ph2.Controls.Remove(DynamicUserControl1);
            //Keep a pipe delimited list of which user controls were removed.  This will increase the 
            //viewstate size if the user keeps removing dynamic controls, but under normal use
            //this is such a small increase in size that it shouldn't be an issue.
            ltlRemoved1.Text += DynamicUserControl1.ID + "|";
            //Also, now that we've removed a user control decrement the count of total user controls on the page
            ltlCount1.Text = (Convert.ToInt16(ltlCount1.Text) - 1).ToString();
        }
        public event EventHandler RemoveUserControl;
        //public event EventHandler adding;
        protected internal void btnRemove_Click(object sender, System.EventArgs e)
        {
            //Raise this event so the parent page can handle it
            
        }
        protected void btnRemove_Click1(object sender, EventArgs e)
        {
            if (this.RemoveUserControl != null)
            {
                this.RemoveUserControl(this, new EventArgs());
            }
        }
        
        protected void btnadd1_Click(object sender, EventArgs e)
        {
            //if (this.adding != null)
            //{
            //    this.adding(this, new EventArgs());
            //}
        }
}
}

Default.aspx
XML
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register src="WebUserControl.ascx" tagname="WebUserControl" tagprefix="uc1" %>

<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        div.demo{
           width:300px;
           float:left;
           padding:20px;
           margin: 10px;
           border: solid black 1px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">

        <asp:ScriptManager ID="sm1" runat="server" />

        <asp:UpdatePanel ID="up1" runat="server">
            <ContentTemplate>

                <div class="demo">
                    <asp:PlaceHolder ID="ph1" runat="server" />
                    <asp:Button ID="btnAdd" runat="server" Text="Add" onclick="btnAdd_Click1" />
                </div>

                <div class="demo">
                    <asp:literal ID="ltlValues" runat="server" />
                    <asp:Button ID="btnDisplayValues" runat="server" Text="Display Values" />
                </div>

            </ContentTemplate>
        </asp:UpdatePanel>
        <!--The text value determines how many items are initially displayed on the page-->
        <asp:Literal ID="ltlCount" runat="server" Text="0" Visible="false" />
        <asp:Literal ID="ltlRemoved" runat="server" Visible="false" />

    </form>

</body>
</html>

Default.aspx.cs

C#
public partial class _Default : System.Web.UI.Page
{

    WebUserControl DynamicUserControl;

    protected void Page_Load(object sender, System.EventArgs e)
    {
        AddAndRemoveDynamicControls();
    }

    private void AddAndRemoveDynamicControls()
    {
        //Determine which control fired the postback event.
//        Control c = ;
//        if(null!= c)
//        {
//            //If the add button was clicked, increase
//           //the count to let the page know we want
//            //to display an additional user control
//            if(c.ID.ToString() = "btnAdd")
//            {
//                ltlCount.Text = (Convert.ToInt16(ltlCount.Text) + 1).ToString();
//            }
////            End If
//        }
        if (null != Request.Form["btnadd"])
        {
            ltlCount.Text = (Convert.ToInt16(ltlCount.Text) + 1).ToString();
        }

        //Be sure everything in the placeholder control is cleared out
        ph1.Controls.Clear();

        int ControlID = 0;

        //Since these are dynamic user controls, re-add them every time the page loads.
        for (int i = 0; i <= (Convert.ToInt16(ltlCount.Text) - 1); i++)
        {
            DynamicUserControl = (WebUserControl)LoadControl("WebUserControl.ascx");

            //If this particular control id has been deleted from the page, DO NOT use it again.  If we do, it will
            //pick up the viewstate data from the old item that had this control id, instead of generating
            //a completely new control.  Instead, increment the control id so we're guaranteed to get a "new"
            //control that doesn't have any lingering information in the viewstate.
            while (InDeletedList("uc" + ControlID) == true)
            {
                ControlID += 1;
            }

            //Note that if the item has not been deleted from the page, we DO want it to use the same control id
            //as it used before, so it will automatically maintain the viewstate information of the user control
            //for us.
            DynamicUserControl.ID = "uc" + ControlID;

            //Add an event handler to this control to raise an event when the delete button is clicked
            //on the user control
            DynamicUserControl.RemoveUserControl += new EventHandler(HandleRemoveUserControl);
            //DynamicUserControl.adding += new EventHandler(NewControl);

            //Finally, add the user control to the panel
            ph1.Controls.Add(DynamicUserControl);
            DynamicUserControl.AddpayControl();
            //DynamicUserControl.adding += new EventHandler(NewControl);
            //Increment the control id for the next round through the loop
            ControlID += 1;
        }
    }

    private bool InDeletedList(string ControlID)
    {
        //Determine if the passed in user control id has been stored in the list of controls that
        //were previously deleted off the page
        string[] DeletedList = ltlRemoved.Text.Split('|');
        for (int i = 0; i <= DeletedList.GetLength(0) - 1; i++)
        {
            if (ControlID.ToLower() == DeletedList[i].ToLower())
            {
                return true;
            }
        }
        return false;
    }

    public void HandleRemoveUserControl(object sender, EventArgs e)
    {
        //This handles delete event fired from the user control

        //Get the user control that fired this event, and remove it
        //WebUserControl DynamicUserControl = sender.Parent;
        //Button but = null;
        //Button but = new Button();
        //but = (Button)sender;

        WebUserControl DynamicUserControl1 = (WebUserControl)sender;
        ph1.Controls.Remove(DynamicUserControl1);

        //Keep a pipe delimited list of which user controls were removed.  This will increase the
        //viewstate size if the user keeps removing dynamic controls, but under normal use
        //this is such a small increase in size that it shouldn't be an issue.
        ltlRemoved.Text += DynamicUserControl1.ID + "|";

        //Also, now that we've removed a user control decrement the count of total user controls on the page
        ltlCount.Text = (Convert.ToInt16(ltlCount.Text) - 1).ToString();
    }

    protected void btnAdd_Click(object sender, System.EventArgs e)
    {
        //Handled in page load
    }

    protected void btnAdd_Click1(object sender, EventArgs e)
    {

    }
}
Posted
Updated 5-Apr-11 6:07am
v3
Comments
brijniks 5-Apr-11 10:22am
   
In WebUserControl.ascx while it is checking for occurance of btnadd1 it is geeting same if for buttons in different user controls.So how can we determine that?
   
Why reading all this long code if you don't explain what's the problem?
--SA
brijniks 5-Apr-11 12:20pm
   
I am having a problem when i am click on Add button of a "WebUserControl.ascx" user control.
When i click on add button "payment.ascx" user control is loaded to all the parent user controls on the page.
I think the problem is in the following line in which it is getting true for all the controls.
"
if (Request.Params.ToString().IndexOf("btnadd1") > 0)
{
ltlCount1.Text = (Convert.ToInt16(ltlCount1.Text) + 1).ToString();
}
"
Please Reply.

I have gone through your code, the issue here is, every time it is a postback, and child control loops through parent number of times, so for every parent control it is getting added. This is a bug in the code, essentially we shouldn't be repeating the payments creation as many number of times webusercontrol exist on the page.

consider the following code.

C#
public partial class WebUserControl : System.Web.UI.UserControl
   {
       Payment p1;
       public delegate void addPaymentHanler(object sender, EventArgs e);
       public event addPaymentHanler addPayment;
       public void addPaymentHandler(object sender, EventArgs e)
       {
           //add it to the parent user control
       }
       public void btn_addClick(object sender, EventArgs e)
       {
           if (this.addPayment != null)
           {
               this.addPayment(sender, e);
           }
       }


I have added addPayment event for WebUserControl, which will be fired on everyclick btnAdd1 on the WebUserControl, and the handler for this can be hooked from the default.aspx.cs page. In AddAndRemoveDynamicControls() method of _Default in for loop

C#
for (int i = 0; i <= (Convert.ToInt16(ltlCount.Text) - 1); i++)
            {
                DynamicUserControl = (WebUserControl)LoadControl("WebUserControl.ascx");

.
.
.


add the following line,

DynamicUserControl.addPayment += new WebUserControl.addPaymentHanler(DynamicUserControl_addPayment);
.
.
}


and have the event handler to add the payment to the current webusercontrol control

MIDL
void DynamicUserControl_addPayment(object sender, EventArgs e)
       {
           //Implement Adding functionality for payment control
           //Follow similar to RemoveUserControl code

       }



Hope this helps.
   
Comments
brijniks 5-Apr-11 23:57pm
   
Thanks for your time,

Do i need to write anything in the
public void addPaymentHandler(object sender, EventArgs e)
{
//add it to the parent user control
}
If no every time i click on add "two" child controls are added to a controls of which i clicked button and one control is added to other parent controls.
If you want i can send u my file.
Kindly Waiting For your reply.
   
the above method you can remove, place where we need to write the payment control addition is

void DynamicUserControl_addPayment(object sender, EventArgs e)
{
//Implement Adding functionality for payment control
//Follow similar to RemoveUserControl code

}
in WebUserControl class, and remove the call DynamicUserControl.AddpayControl(); from for loop in the default.aspx
Can you reduce the code sample to its most basic form to show the problem in a more straightforward manner? As well as making the problem easier to see for yourself you will generally get better responses from people looking to solve it :)
Get rid of the application specifics and reduce it to the exact problem
   
Comments
brijniks 5-Apr-11 12:16pm
   
Ok.thanks
My page contains more than "WebUserControl" controls.
When i click on add button of one of this control child control-"payment.ascx" is added to all the user controls-"Web User Control".
I want that when i click on specific add button then payment.ascx should be added to specific user control.
I think the problem is in the line of "WebUserControl.ascx" where i am checking whether btnadd1 is clicked or not..For all controls it is getting true value.
if (Request.Params.ToString().IndexOf("btnadd1") > 0)
{
ltlCount1.Text = (Convert.ToInt16(ltlCount1.Text) + 1).ToString();
}
brijniks 5-Apr-11 12:20pm
   
I am having a problem when i am click on Add button of a "WebUserControl.ascx" user control.
When i click on add button "payment.ascx" user control is loaded to all the parent user controls on the page.
I think the problem is in the following line in which it is getting true for all the controls.
"
if (Request.Params.ToString().IndexOf("btnadd1") > 0)
{
ltlCount1.Text = (Convert.ToInt16(ltlCount1.Text) + 1).ToString();
}
"
Please Reply.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900