简体   繁体   English

在运行时添加控件Form Builder

[英]Adding Controls at runtime Form Builder

I am using the following code to add items to a panel but the problem is its only allowing me to add one instance of a control, I want to be able to add as many items as I want to the panel and i thought the following code would acheieve that. 我正在使用以下代码向面板添加项目,但问题是它仅允许我添加一个控件实例,我希望能够向面板添加尽可能多的项目,并且我认为以下代码会做到的。

 if (ctrlType.SelectedValue == "TextBox")
        {
            listElements.Add(new XElement(@"TextBox", new XElement("name"),
                                  new XElement("Type", "System.String"),
                                    new XElement("displayName", this.txtTitle.Text.ToString()),
                                    new XElement("length", txtMaxLength.Text.ToString()),
                                     new XElement("key", false),
                                     new XElement("required",  chkRequired.Checked)));


            TextBoxUserControl tb2 =
                         (TextBoxUserControl)LoadControl(@"~\UserControls\TextBoxUserControl.ascx");
            tb2.XMLText = listElements;
            tb2.Text = txtTitle.Text;
            tb2.Name = "TextBox" + " " + ctrlSource.SelectedValue.ToString() + " " + Guid.NewGuid().ToString();
            pnlControls.Controls.Add(tb2);

        }

        if (ctrlType.SelectedValue == "DropDown" && ctrlSource.SelectedValue == "0")   {
            listElements.Add(new XElement(@"ClassficationEnum", new XElement("name", "TestForm"),
                new XElement("Guid", "1f77f0ce-9e43-340f-1fd5-b11cc36c9cba"),
                                     new XElement("Type", "System.String"),
                                       new XElement("displayName", this.txtTitle.Text.ToString()),
                                       new XElement("length", txtMaxLength.Text.ToString()),
                                        new XElement("key", false),
                                        new XElement("required",  chkRequired.Checked)));


            Classfication clafficationDp =
                    (Classfication)LoadControl(@"~\UserControls\Classfication.ascx");
            clafficationDp.ID = "clafficationDp" + " " + ctrlSource.SelectedValue.ToString() + " " + Guid.NewGuid().ToString();
            clafficationDp.Text = txtTitle.Text;
            pnlControls.Controls.Add(clafficationDp);



        }
        else if (ctrlType.SelectedValue == "DropDown" && ctrlSource.SelectedValue == "1")
        {
            listElements.Add(new XElement(@"SourceEnum", new XElement("name", "TestForm"),
                new XElement("Guid", "5d59071e-69b3-7ef4-6dee-aacc5b36d898.xml"),
                                     new XElement("Type", "System.String"),
                                       new XElement("displayName", this.txtTitle.Text.ToString()),
                                       new XElement("length", txtMaxLength.Text.ToString()),
                                        new XElement("key", false),
                                        new XElement("required", chkRequired.Checked)));



            SourceEnum dpsource =
                         (SourceEnum)LoadControl(@"~\UserControls\SourceEnum.ascx");
            dpsource.ID = "DropList" + " " + ctrlSource.SelectedValue.ToString() + " " + Guid.NewGuid().ToString();
            dpsource.Text = txtTitle.Text;
            pnlControls.Controls.Add(dpsource);

        }
        UpdateActiveControl("Test", "Form Name", "Test Control", listElements);



        pnlControls.Controls.Add(new LiteralControl("<br />"));
  //      formControls = formGen.GetFormDataFromService();
        foreach (XElement formControl in listElements)
         {

             FormStructure frmstructure = new FormStructure();

             frmstructure.displayname = formControl.Element("displayName").Value;
             frmstructure.Required = Convert.ToBoolean(formControl.Element("required").Value);
             frmstructure.length = formControl.Element("length").Value;
             frmstructure.ControlType = formControl.Element("Type").Value;                


             formControls.Add(frmstructure);
         }

This is where I load the details of form controls 这是我加载表单控件详细信息的地方

 public partial class _default : System.Web.UI.Page
{

    PortalContext portalContext = new PortalContext();
    DataAccess da = new DataAccess();
    FormGenerator formGen = new FormGenerator();
    List<FormStructure> formControls = new List<FormStructure>();
    List<XElement> listElements = new List<XElement>();

    protected void Page_Load(object sender, EventArgs e)
    {
        da.SqlInstanceName = "CDDEVSVR-SQL";
        da.PortalDatabaseName = "PortalCms";
        da.IntegratedSecurity = true;
        SetEntityContextConnectionStrings();

        if (!IsPostBack)
        {
            formControls = formGen.GetFormDataFromService();
        }
        foreach (FormStructure formControl in formControls)
        {


            if (formControl.ControlType == "TextBox")
            {
                listElements.Add(new XElement(@"TextBox", new XElement("name"),
                                new XElement("Type", "System.String"),
                                  new XElement("displayName", this.txtTitle.Text.ToString()),
                                  new XElement("length", txtMaxLength.Text.ToString()),
                                   new XElement("key", false),
                                   new XElement("required", chkRequired.Checked)));



                TextBoxUserControl textBoxControl =
                    (TextBoxUserControl)LoadControl(@"~\UserControls\TextBoxUserControl.ascx");
                textBoxControl.XMLText = listElements;
                textBoxControl.Text = formControl.displayname;

                pnlControls.Controls.Add(textBoxControl);
                pnlControls.Controls.Add(new LiteralControl("<br />"));


            }

            if (formControl.ControlType == "DropDown")
            {
                listElements.Add(new XElement(@"ClassficationEnum", new XElement("name", "TestForm"),
                     new XElement("Guid", "1f77f0ce-9e43-340f-1fd5-b11cc36c9cba"),
                                          new XElement("Type", "System.String"),
                                            new XElement("displayName", this.txtTitle.Text.ToString()),
                                            new XElement("length", txtMaxLength.Text.ToString()),
                                             new XElement("key", false),
                                             new XElement("required", chkRequired.Checked)));


                SourceEnum dpsource =
                     (SourceEnum)LoadControl(@"~\UserControls\SourceEnum.ascx");
                dpsource.ID = "DropList" + " " + ctrlSource.SelectedValue.ToString() + " " + Guid.NewGuid().ToString();
                dpsource.Text = formControl.displayname;
                pnlControls.Controls.Add(dpsource);




            }
        }
    }

I have done some amateur level work dynamically adding user controls in a collection-like manner to ASP.NET web forms and was able to get it to work correctly. 我已经完成了一些业余级别的工作,以类似于集合的方式将用户控件动态添加到ASP.NET Web表单中,并且能够使其正常工作。 If your problem is as @rene suggests where you are only seeing one control persist through postback, it might be because of a page render process problem as described in this question answer and as @ovm suggests; 如果您的问题是@rene建议您仅在回传中看到一个控件存在的地方,则可能是由于该问题答案中所述和@ovm建议的页面渲染过程问题。 each page render has to re-generate the controls, I was able to do that using arrays stored in a for-purpose session variable. 每个页面渲染都必须重新生成控件,我能够使用存储在专用会话变量中的数组来做到这一点。

That said, while working on the feature, several blog posts suggested that it was not a terrific idea, and seeing the way it works in the page generation and rendering, I agree. 也就是说,在使用此功能时,有几篇博客文章建议这不是一个好主意,我同意看到它在页面生成和呈现中的工作方式。 I don't expect to have an easy time ajaxing the dynamic section of the page or otherwise improving it later. 我不希望轻易中断页面的动态部分或稍后进行其他改进。 The common (two blogs, maybe) workaround was to design to have all the controls you could possibly need already built into the page, then hide and don't serve the ones that you don't need for a given page render. 常见的解决方法(可能是两个博客)是设计成将可能需要的所有控件内置到页面中,然后隐藏而不提供给定页面渲染不需要的控件。 HTH HTH

You have to keep track of all controls that you have already added to the panel and re-add them on postback. 您必须跟踪已经添加到面板中的所有控件,并在回发时将它们重新添加。

If those controls should be Event-Aware, you should add them during the OnInit Phase of the page lifecycle. 如果这些控件应该是事件感知的,则应在页面生命周期的OnInit阶段添加它们。

update 更新

Your initialization of the formControls variable is not guaranteed to persist each postback across multiple requests. 不保证您对formControls变量的初始化可以在多个请求之间保留每次回发。 What you could do is keep track of the FormStructure instances in the HttpContext.Current.Cache and recreate the controls during the OnInit stage based on the FormStructures in the Cache. 您可以做的是跟踪HttpContext.Current.Cache中的FormStructure实例,并在OnInit阶段基于缓存中的FormStructures重新创建控件。

private List<FormStructure> GetFormStructureStore () {
  IList<FormStructure> formControls = (IList<FormStructure>)HttpContext.Current.Cache["FormControlsKey"];
  if(formControls == null)
  {
    formControls = new List<FormStructure>();
    HttpContext.Current.Cache.Add(formControls);
  }
  return formControls;
}

protected override void OnInit(EventArgs e)
{
  IList<FormStructure> formControls = GetFormStructureStore();
  // load the controls and add them to the Controls collection
  // ...
}

You can now use this method to get the formControls from Cache and remove the Page level variable. 现在,您可以使用此方法从缓存中获取formControls并删除Page级变量。

//List<FormStructure> formControls = new List<FormStructure>();

Also, can you show us what 另外,你能告诉我们什么

formGen.GetFormDataFromService();

is actually returning? 真的回来了吗?

I am asking this because even if the contents of formControls is lost at some point in the Session, if GetFormDataFromService() returns multiple FormStructures, those should actually be visible. 我之所以这样问是因为,即使FormControls的内容在会话中的某个时刻丢失了,如果GetFormDataFromService()返回多个FormStructures,则这些实际上应该是可见的。

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

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