Setting values of UserControls used multiple times on a page

Discussion in 'ASP .Net Building Controls' started by Grant Ord, Dec 15, 2004.

  1. Grant Ord

    Grant Ord Guest

    I have a pages which use the same UserControl multiple times on the same page
    - they have different IDs though. The UserControl contains a number of select
    lists.

    After databinding each select list in each control to a datasource, which
    happens correctly, I then set the Value property for each select list to a
    known value obtained from a query.

    The problem is that only the last Control loaded actually gets its value set
    when the page is displayed.

    Can anyone tell me what is wrong?
     
    Grant Ord, Dec 15, 2004
    #1
    1. Advertisements

  2. Hi Grant,

    Thanks for your posting. From your description, you've an asp.net page
    which contains serveral instance of a certain ASP.NET ASCX user control
    which also contains some dropdownlist controls. And when you bind some
    datasource to those dropdownlists and set a initial selectedValue for them,
    you found only the last one you set take effect, yes?

    As for this problem, I'm not sure whether the problem is something
    concerned to how you loaded control or the code logic in your ascx user
    control. Are you put the UserControls onto page staticaly or use
    Page.LoadControl to load them dynamically. In addition, I suggest that you
    try make a simple repro page and provide some code of your control(could be
    a simplified version) and test page so that we can look a bit more deep
    into it . thanks.

    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
     
    Steven Cheng[MSFT], Dec 16, 2004
    #2
    1. Advertisements

  3. Grant Ord

    Grant Ord Guest

    Hi Steve
    Thanks for your response.
    Here is an abbreviated code extract - I think it contains all the relevant
    code and illustrates what is happening.
    The control is used four times on the hosting page.
    Each control contains seven HtmlSelects and one HtmlInputHidden.
    In essence Fill() and Page.DataBind() works fine - the content of three of
    the HtmlSelects should be different in each control, and it is, so the
    databinding is being correctly applied to each individual control.
    MakeSelection() only is only effective for the last control to go through
    the foreach loop on the hosting page.
    On the first three there is no 'selected' property in the html for the
    options for the HtmlSelects LvlCncrnTypID, IsSupNdID, SupTypID but there is
    on the last one.
    I've stepped through the whole process in the dubugger and everything
    executes identically for each control.


    In the hosting aspx.cs page:

    private void Page_Load(object sender, System.EventArgs e)
    {
    Mentl = (VSDWeShefSSL.inc.Support)LoadControl("../inc/Support.ascx");
    Mentl.TblID = TblIDs.MentalHealth;
    Mentl.ID = "Mentl";
    CtlsPH.Controls.Add(Mentl);
    Genrl = (VSDWeShefSSL.inc.Support)LoadControl("../inc/Support.ascx");
    Genrl.TblID = TblIDs.GeneralHealth;
    Genrl.ID = "Genrl";
    CtlsPH.Controls.Add(Genrl);
    Dentl = (VSDWeShefSSL.inc.Support)LoadControl("../inc/Support.ascx");
    Dentl.TblID = TblIDs.DentalHealth;
    Dentl.ID = "Dentl";
    CtlsPH.Controls.Add(Dentl);
    Sight = (VSDWeShefSSL.inc.Support)LoadControl("../inc/Support.ascx");
    Sight.TblID = TblIDs.SightHealth;
    Sight.ID = "Sight";
    CtlsPH.Controls.Add(Sight);

    foreach (VSDWeShefSSL.inc.Support c in CtlsPH.Controls)
    {
    c.RegID = NewReg;
    }
    }

    In the control ascx.cs page:
    public class Support : System.Web.UI.UserControl
    {
    protected System.Web.UI.HtmlControls.HtmlSelect LvlCncrnTypID;
    protected System.Web.UI.HtmlControls.HtmlSelect IsSupNdID;
    protected System.Web.UI.HtmlControls.HtmlSelect SupTypID;
    protected System.Web.UI.HtmlControls.HtmlSelect AgencyID;
    protected System.Web.UI.HtmlControls.HtmlSelect BasicAgencyID;
    protected System.Web.UI.HtmlControls.HtmlSelect SpeclAgencyID;
    protected System.Web.UI.HtmlControls.HtmlSelect RehabAgencyID;
    protected System.Web.UI.HtmlControls.HtmlInputHidden SupList;

    private DataTable dt;

    private void Page_PreRender(object sender, System.EventArgs e)
    {
    AgencyID.Attributes["onchange"] = "onchange" + this.ID + "_AgencyID();";
    BindPagedData();

    }

    private void BindPagedData()
    {
    Fill();
    Page.DataBind();
    MakeSelection();
    }

    private void Fill()
    {
    LvlCncrnTypID.DataSource =
    VSDWeShefSSL.DDLData.HardCodeLists.LvlCncrnTyp();
    LvlCncrnTypID.DataValueField = "LvlCncrnTypID";
    LvlCncrnTypID.DataTextField = "LvlCncrnTyp";
    IsSupNdID.DataSource = VSDWeShefSSL.DDLData.HardCodeLists.IsSupNd();
    IsSupNdID.DataValueField = "IsSupNdID";
    IsSupNdID.DataTextField = "IsSupNd";
    string rehabSupTyp = SupTyp.TblIDs.ToString();
    SupTypID.DataSource = VSDWeShefSSL.DDLData.HardCodeLists.SupTyp();
    SupTypID.DataValueField = "SupTypID";
    SupTypID.DataTextField = "SupTyp";
    AgencyID.DataSource = GetAgencyID();
    AgencyID.DataValueField = "AgencyID";
    AgencyID.DataTextField = "Organisation";
    BasicAgencyID.DataSource = GetSupTypAgencyID(G.SUP_TYP_BASIC_ADVICE);
    BasicAgencyID.DataValueField = "AgencyID";
    BasicAgencyID.DataTextField = "Organisation";
    SpeclAgencyID.DataSource = GetSupTypAgencyID(G.SUP_TYP_SPECIALIST_ADVICE);
    SpeclAgencyID.DataValueField = "AgencyID";
    SpeclAgencyID.DataTextField = "Organisation";
    RehabAgencyID.DataSource =
    GetSupTypAgencyID(G.SUP_TYP_REHABILITATION_SERVICE);
    RehabAgencyID.DataValueField = "AgencyID";
    RehabAgencyID.DataTextField = "Organisation";
    dt = (DataTable)GetSelection();
    SupList.Value = (dt.Rows[0]["SupList"] != null) ?
    dt.Rows[0]["SupList"].ToString() : "";
    }

    private void MakeSelection()
    {
    if (dt.Rows.Count > 0)
    {
    LvlCncrnTypID.Value = (dt.Rows[0]["LvlCncrnTypID"] != null) ?
    dt.Rows[0]["LvlCncrnTypID"].ToString() : "";
    IsSupNdID.Value = (dt.Rows[0]["IsSupNdID"] != null) ?
    dt.Rows[0]["IsSupNdID"].ToString() : "";
    SupTypID.Value = (dt.Rows[0]["SupTypID"] != null) ?
    dt.Rows[0]["SupTypID"].ToString() : "";
    }
    else
    {
    LvlCncrnTypID.Value = "";
    IsSupNdID.Value = "";
    SupTypID.Value = "";

    }

    }

    public ICollection GetSupTypAgencyID(int supTypID)
    {
    ..........
    DataView dv = new DataView(dt);
    return dv;
    }
    public ICollection GetAgencyID()
    {
    .............
    DataView dv = new DataView(dt);
    return dv;
    }
    public DataTable GetSelection()
    {
    DataSet lists = new DataSet();
    DataTable dt = new DataTable();
    ..........
    return dt;
    }
    }

    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
    InitializeComponent();
    base.OnInit(e);
    }
    private void InitializeComponent()
    {
    this.PreRender += new System.EventHandler(this.Page_PreRender);
    }
    #endregion
    }
     
    Grant Ord, Dec 16, 2004
    #3
  4. Hi Grant,

    Thanks for your response. Just have a look at the code you provided, I
    think the problem is likely due to the
    "Page.DataBind" you called in each UserControl's PreRender event. Your
    UserControl's PreRender is like below:

    private void Page_PreRender(object sender, System.EventArgs e)
    {
    //I remove the function call stack
    Fill();
    Page.DataBind();
    MakeSelection();
    }

    So when you have multi UserControls and each control will call PreRender
    before Page Render out and the Page.DataBind() will recursively fire all
    its sub controls' DataBind(), that means the sequence will be something
    like: (suppose we have loaded 4 UserControls)

    Page_PreRender ....

    ---------Control1-------------
    ***Control1 PreRender

    ***Page.DataBind();

    *******Control1 DataBind()
    *******Control2 DataBind()
    *******Control3 DataBind()
    *******Control4 DataBind()

    ***MakeSelection();

    ---------Control2-------------
    ***Control2 PreRender

    ***Page.DataBind();

    *******Control1 DataBind()
    *******Control2 DataBind()
    *******Control3 DataBind()
    *******Control4 DataBind()

    ***MakeSelection();


    ........



    Then, we can see that since the Page.DataBind make all the 4 UserControls
    rebind the data(the dropdownlist) , so only the final DropDownList's
    assigned SelectedIndex will remain, others' are lost.
    Do you think so?

    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
     
    Steven Cheng[MSFT], Dec 17, 2004
    #4
  5. Grant Ord

    Grant Ord Guest

    Hi Steve

    Thanks for your help.
    Your explanation did highlight the issue for me.
    I moved the databinding code into a Page_Load function and called the
    controles value selections from a PreRender function, that way the bound
    values weren't lost.
     
    Grant Ord, Dec 17, 2004
    #5
  6. You're welcome Grant,

    Glad that my suggestions are of assistance.
    Have a good day!

    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
     
    Steven Cheng[MSFT], Dec 20, 2004
    #6
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.