【问题标题】:UserControl Within Template of another UserControl Loses values on postback另一个用户控件模板内的用户控件在回发时丢失值
【发布时间】:2012-01-27 15:24:30
【问题描述】:

这可能是真正错误的做法,所以如果是,请告诉我!我有一个名为 ucDropDownList.ascx 的用户控件。它基本上是一个下拉菜单,旁边有一个按钮。单击该按钮时,将出现一个 jquery 对话框。对话框就是问题所在。由于此用户控件用于我想要的许多地方(在 OOP 原则内),以允许我们根据下拉列表以不同的形式加载...所以我选择了模板用户控件。其背后的代码如下:

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()
   {
   }
 }

然后我(将)拥有几个用户控件,这些用户控件是我将拥有这些用户控件的每种类型的简单表单......(给出的示例是数据库中的状态表)。没有什么令人兴奋的,只是所有的控件都启用了 viewState。 (几乎与它的标准一样)。

我展示这些的页面有一些像这样的标记......

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

还有像这样的幕后...

  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);
  }

当 SaveRecord 运行时(此方法是基于 ucEdStatus1 控件上各种控件的值的简单插入数据库),ucEdStatus 上的控件都是标记中设置的默认值,并且没有维护用户输入的内容(因此保存只是保存了错误的数据)。

我愿意接受建议和批评。如果您需要更多信息,我可以给您,我只需要帮助了解为什么会发生这种情况。

编辑 以防万一你们想知道这是 ucEdStatus 控件的类。它可能会回答为什么我仍在摸不着头脑,或者可能表明我是多么愚蠢。

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;
  }
}

【问题讨论】:

  • 您的代码看起来不错,实际上我无法重现该问题。当页面回发时,页面上的其他控件是否保留其值?
  • 是的,我在页面上有另一个用户控件,它没有模板,并且按钮单击时控件中的值仍然存在。关于模板中的那个控件的一些东西。我不认为您可以将有效的代码发送给我:-p
  • 我将你的代码隐藏用于 ucDropDownList;在 .ascx 中,我放置了一个 PlaceHolder (phNewRecordForm) 和一个按钮 (SaveButton)。在 ucEdStatus.ascx 我放了一个 TextBox (回发后保留其值)。在主页中,我使用了您的标记,减去 OnSaveClicked 属性。就是这样。我没有实现用初始值填充控件的功能。
  • 尝试注释掉所有处理加载和保存控件值的代码,只保留 InstantiateIn 调用来测试基本的回发机制。
  • 已添加 ucEdStatus 控件的代码。如您所见,我并没有真正添加默认值。我是在做一些愚蠢的事情还是不可能?

标签: c# asp.net user-controls viewstate controltemplate


【解决方案1】:

尝试每次在 page_init 中初始化该控件;换句话说,删除!IsPostback 检查。所有控件都必须在页面初始化期间初始化,然后才能应用它们的视图状态信息。这与在 aspx/ascx 文件中定义 asp.net 控件完全相同(这些文件中的任何内容都经过相同的过程,由 asp.net 自动为您完成)。

【讨论】:

  • 对不起老兄,刚刚回到这个问题!试过了,并没有改变任何东西。
【解决方案2】:

所以我环顾四周后找到了答案。 This site 真的很有帮助。问题是 jquery 模式弹出(对话框)在回发时迷失了自己。一行修复。多么令人沮丧!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多