简体   繁体   English

ASP.NET-初始化在转发器中创建的用户控件的正确方法?

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

Relevant code from DetailsBERS.ascx file: DetailsBERS.ascx文件中的相关代码:

<%@ 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: 来自DetailsBERS.ascx.cs文件的相关代码:

 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: BERS.ascx.cs文件中的相关代码:

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. 好的,现在我的问题/问题源于我对ASP.net的了解不多,以及如何使用其创造性的方式来初始化和创建控件。

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. 如果我使用上面的方法,它会在开始时起作用,直到我进行回发(通过单击按钮)并尝试再次获取IdBers-txtTest.Text ==“”并得到一个例外。 (Same result if I use the private int _idBers as the basis for IdBers.) (如果我使用私有int _idBers作为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... 我认为问题在于我的IdBers在游戏后期分配,因此没有保存在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")%>')? 如果不通过将其分配给DetailsBERS.ascx文件中的IdBers属性(IdBers ='<%#DataBinder.Eval(Container,“ DataItem.id_bers”)%>')),我应该如何创建/初始化我的BERS控件? (I have since implemented Viewstate as suggested by jdt199, so this part is resolved - thanks jdt199.) (此后,我已按照jdt199的建议实施了Viewstate,因此此部分已解决-感谢jdt199。)

More importantly, I need this value within my OnInit stage so I can present the correct data within the control - is this possible? 更重要的是,我需要在OnInit阶段使用此值,以便可以在控件中显示正确的数据-这可能吗? (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. 如果使用IdBers属性而不是文本框本身设置viewstate,则可以避免由于从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: 我最终的解决方案是使用ViewState,但是诀窍是通过在DataSource属性中设置此公共属性来进行设置:

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 %>"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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