1

This may be the really wrong way of doing this and so if it is please let me know!! I have a user control called ucDropDownList.ascx. It basically is a drop down with a button besides it. When the button is clicked a jquery dialog appears. The dialog is the problem. As this user control is used in a number of places i wanted (within the principles of OOP) to allow us to load in a different form depending on which drop down it was...So i went for Template User Control. The code behind for this is as follows:

public partial class ucDropDownList : System.Web.UI.UserControl

 {

   private ITemplate m_RecordForm = null;

   [TemplateContainer(typeof(cPopUpContainer))]
   [PersistenceMode(PersistenceMode.InnerProperty)]
   public ITemplate RecordForm
   {
     get { return m_RecordForm; }
     set { m_RecordForm = value; }
   }

   protected void Page_Load(object sender, EventArgs e)
   {

   }

   void Page_Init()
   {
     // Load in the Template control (we use this for making the different types of form!
     if (RecordForm != null)
     {
       cPopUpContainer container = new cPopUpContainer();
       m_RecordForm.InstantiateIn(container);
       phNewRecordForm.Controls.Add(container);
     }
   }

   public event EventHandler SaveClicked;
   protected void SaveButton_Clicked(object sender, EventArgs e)
   {
     if (SaveClicked != null)
       SaveClicked(this, e);
   }
 }

 public class cPopUpContainer: Control, INamingContainer
 {
   internal cPopUpContainer()
   {
   }
 }

Then i (will) have several user controls that are simple forms for each of the types that i will have these user controls for...(example given is a status table in the database). There is nothing exciting there, just that all of the controls have viewState Enabled. (pretty much as standard as it comes).

The page that i show these on has some markup like so...

<uc3:ucDropDownList ID="comboStatus" runat="server" OnSaveClicked="comboStatus_Saved">
                    <RecordForm>
                        <uc4:ucEdStatus ID="ucEdStatus1" runat="server" ViewStateMode="Enabled" />
                    </RecordForm>
                </uc3:ucDropDownList>

and a behind the scenes like so...

  protected void Page_Init(object sender, EventArgs e)
  {
     if (!IsPostBack)
    {
      ucEdStatus statForm = comboStatus.Controls[3].Controls[0].FindControl("ucEdStatus1") as ucEdStatus;
      statForm.InitializeControl(false);
    }
   } 

  protected void Page_Load(object sender, EventArgs e)
  {

  }

  protected void comboStatus_Saved(object sender, EventArgs e)
  {
    ucEdStatus statForm = comboStatus.Controls[3].Controls[0].FindControl("ucEdStatus1") as ucEdStatus;
    statForm.SaveRecord(eSaveUCEdType.Insert);
  }

When the SaveRecord runs(this method is a simple insert into the database which is based on the values of the various controls on the ucEdStatus1 control) the controls on the ucEdStatus are all the default as set in the markup and non have maintained what the user put in (therefore the save just saves a wrong bit of data).

I am open to suggestions and criticism. If you need more information i can give it to you, i just need help in understanding why this is happening.

EDIT Just in case you guys were wondering this is the class for the ucEdStatus control. It may answer why i am still scratching my head or may show how stupid i am.

long m_RecordID
{
  get { return (ViewState["recordid"] != null ? Convert.ToInt64(ViewState["recordid"]) : -1); }
  set { ViewState["recordid"] = value; }
}

bool m_isSupport
{
  get { return (ViewState["isSupport"] != null ? Convert.ToBoolean(ViewState["isSupport"]) : false); }
  set { ViewState["isSupport"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
}

//--------------------------------------------------------------------------------
public void InitializeControl(bool aIsSupport)
{
  //Setup the issupport variable
  m_isSupport = aIsSupport;

  //Add the importance to the mixup...
  Array importanceTexts = System.Enum.GetNames(typeof(eStatusImportance));

  for (int i = 0; i <= importanceTexts.Length - 1; i++)
  {
    ListItem item = new ListItem(importanceTexts.GetValue(i).ToString(), i.ToString());
    comboImportance.Items.Add(item);
  }
}

//--------------------------------------------------------------------------------
public long SaveRecord(eSaveUCEdType aSaveType)
{
  using (cDBConnection con = new cDBConnection(this.Page, true))
  {
    cStatus stat = new cStatus(con.Con, m_RecordID);
    if (m_RecordID == -1)
      stat.Id = cGlobalDB.NewKey();

    stat.Importance = Convert.ToInt32(comboImportance.SelectedValue);
    stat.Name = txtName.Text;
    stat.Issupport = m_isSupport;
    stat.Color = edColor.Color;
    stat.SaveChanges((aSaveType == eSaveUCEdType.Insert ? eUpdateType.insert : eUpdateType.update));
    return (long)stat.Id;
  }
}
Daniel Casserly
  • 3,552
  • 2
  • 29
  • 60
  • Your code looks fine, and in fact I was unable to reproduce the issue. When the page posts back, do other controls on the page retain their values? – Michael Liu Jan 27 '12 at 15:50
  • Yes, i have another user contrl that is on the page that has no templates and the values from the controls of that are still there on the button click. Something about that control that is in the template. I don't suppose you could send me the code that works :-p – Daniel Casserly Jan 27 '12 at 15:55
  • I used your code-behind for ucDropDownList; in the .ascx I put a PlaceHolder (phNewRecordForm) and a Button (SaveButton). In ucEdStatus.ascx I put a TextBox (whose value was retained after a postback). In the main page I used your markup, minus the OnSaveClicked attribute. And that's it. I didn't implement functionality to populate the controls with initial values. – Michael Liu Jan 27 '12 at 16:18
  • Try commenting out all code dealing with loading and saving the values of the controls, keeping only the InstantiateIn call to test the basic postback mechanism. – Michael Liu Jan 27 '12 at 16:21
  • Have added the code for the ucEdStatus control. As you can see i don't really add default values. Am i doing something stupid or is it possibly not possible? – Daniel Casserly Jan 27 '12 at 21:43
  • What about the .ascx for ucDropDownList and ucEdStatus? And exactly which control(s) aren't retaining their values across postbacks? – Michael Liu Jan 27 '12 at 21:49
  • Anything in the ucEdStatus. The Method SaveRecord when called from the main page is not returning the correct values from any of the controls. – Daniel Casserly Jan 28 '12 at 08:55
  • Try adding an `` to ucEdStatus. **Don't** get or set its value, or access it in any way, in the code-behind. Does the text box retain user-entered text across postbacks? – Michael Liu Jan 29 '12 at 03:24
  • If you are interested i found the answer. Thanks for all of your help though. – Daniel Casserly Feb 03 '12 at 09:37

2 Answers2

0

Try initializing that control in page_init every time; in other words, remove the !IsPostback check. All controls have to be initialized during page-init before their viewstate information will be applied. This is exactly equivalent as defining an asp.net control within aspx/ascx files (whatever is in those files goes through the same process, automatically for you done by asp.net).

0

So i found the answer after a little looking around. This site really helped. The problem was the jquery modal pop up (dialog) was losing itself on post back. One line fix. How frustrating!

Community
  • 1
  • 1
Daniel Casserly
  • 3,552
  • 2
  • 29
  • 60