在运行时添加控件表单生成器
本文关键字:表单 控件 运行时 添加 | 更新日期: 2023-09-27 18:13:09
我使用下面的代码来添加项目到面板,但问题是它只允许我添加一个控件的实例,我希望能够添加尽可能多的项目,因为我想面板,我认为下面的代码将实现这一点。
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);
}
这是加载表单控件详细信息的地方
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);
}
}
}
我做过一些业余水平的工作,以类似于集合的方式动态地向ASP添加用户控件。NET web表单,并能够使其正常工作。如果您的问题是@rene所建议的,您只看到一个控件通过回发持续存在,这可能是因为在这个问题的答案中描述的页面呈现过程问题和@ovm所建议的;每次页面渲染都必须重新生成控件,我可以使用存储在专用会话变量中的数组来做到这一点。
也就是说,在开发该功能时,一些博客文章认为这不是一个了不起的想法,看到它在页面生成和呈现中的工作方式,我同意。我并不期望能够轻松地修改页面的动态部分,或者稍后对其进行改进。常见的解决方法(可能是两个博客)是在设计时将可能需要的所有控件都内置到页面中,然后隐藏并且不提供给定页面呈现不需要的控件。HTH
您必须跟踪已经添加到面板中的所有控件,并在回发时重新添加它们。
如果这些控件应该是事件感知的,你应该在页面生命周期的OnInit阶段添加它们。
formControls变量的初始化不能保证在多个请求中持久化每个回发。你可以做的是跟踪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
// ...
}
你现在可以使用这个方法从缓存中获取formControls并删除Page level变量。
//List<FormStructure> formControls = new List<FormStructure>();
还有,你能告诉我们
formGen.GetFormDataFromService();
实际上是返回吗?
我问这个,因为即使formControls的内容在会话中的某些时候丢失,如果GetFormDataFromService()
返回多个FormStructures,这些实际上应该是可见的。