简体   繁体   中英

ASP.NET - Proper way to initialize a user control created in a repeater?

Relevant code from DetailsBERS.ascx file:

<%@ Register Src="BERS.ascx" TagName="BERS" TagPrefix="ucBERS" %>


<asp:Repeater ID="repeatBERS" runat="server"><ItemTemplate>
 <tr>
 <td id="Td1" runat="server">
  <asp:TextBox runat="server" ID="txtTest" Text='<%#DataBinder.Eval(Container, "DataItem.id_bers")%>' MaxLength='<%#DataBinder.Eval(Container, "DataItem.id_bers")%>' />
  <ucBERS:BERS ID="ucBERS" runat="server" IdBers='<%#DataBinder.Eval(Container, "DataItem.id_bers")%>' />
 </td>
 </tr>
</ItemTemplate></asp:Repeater>

Relevant code from DetailsBERS.ascx.cs file:

 protected void ddlPartie_SelectedIndexChanged(object sender, EventArgs e)
 {
  IdPartieStage = Convert.ToInt32(ddlPartie.SelectedValue);
  DisplayBers();
  upDetailsBERS.Update();
 }

 private void DisplayBers()
 {
  using (SqlCommand cmd = new SqlCommand(Resources.Select.GetBersList,
   new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString)))
  {
   try
   {
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@idPartieStage", IdPartieStage);
    cmd.Connection.Open();
    SqlDataReader read = cmd.ExecuteReader();

    repeatBERS.DataSource = read;
    repeatBERS.DataBind();
   }
   catch (Exception ex)
   {
    throw new Exception("Could not DisplayBers().", ex);
   }
   finally
   {
    if (cmd != null)
     cmd.Connection.Close();
   }
  }
 }

Relevant code from BERS.ascx.cs file:

protected override void OnPreRender(EventArgs e)
 {
  base.OnPreRender(e);

  PopulateControls();
  PopulateBasicBersInfo();
 }

 private int _idBers;
 public int IdBers
 {
  //set { _idBers = value; }
  set { txtTest.Text = value.ToString(); }
  //get { return _idBers; }
  get { return Convert.ToInt32(txtTest.Text); }
 }

OK, now my question/problem stems with my weak grasp of ASP.net and how to work with its creative way of initializing and creating controls.

If I use the above it works, in the beginning, until I do a postback (from button click) and try to get at IdBers again - txtTest.Text == "" and I get an exception. (Same result if I use the private int _idBers as the basis for IdBers.)

I believe the problem lies with the fact that my IdBers gets assigned late in the game and so isn't saved in the viewstate...

How am I supposed to create/initialize my BERS control if not by assigning to its IdBers property in the DetailsBERS.ascx file (IdBers='<%#DataBinder.Eval(Container, "DataItem.id_bers")%>')? (I have since implemented Viewstate as suggested by jdt199, so this part is resolved - thanks jdt199.)

More importantly, I need this value within my OnInit stage so I can present the correct data within the control - is this possible? (Question suggested in my title but which I forgot to include into the post's main text.)

If you set viewstate using the IdBers property rather than the textbox itself you can avoid the page lifecycle issues you are seeing as the value is read from the viewstate.

 public int IdBers
 {
     set { VeiwState["IdBers"] = value; }    
     get { 
             int idBerVal = 0;
             if(VeiwState["IdBers"] != null)
             {
                 int.TryParse(VeiwState["IdBers"].ToString(), out idBerVal);
             }
             return idBerVal; 
         }
 }


protected void Page_Load(object sender, EventArgs e)
{
    txtTest.Text = IdBers.ToString();
}

My eventual solution was using ViewState but the trick was to set this public property by setting it in a DataSource property:

public Object DataSource
{
    get { return _datasource; }
    set
    {
        _datasource = value;
        if (_datasource != null)
        {

This data is passed from the parent user control:

<ucBERS:BERS ID="ucBERS" runat="server"
    DataSource="<%# Container.DataItem %>"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM