持久化动态生成的控件.net
persist dynamically generated controls .net
我想在单击按钮时添加一组新的 .net 控件和 html 标记。
此时我有一个占位符,我在 VB.Net 中从后面的代码动态添加控件,这是正确的,但是,只要有回发(当单击按钮或下拉菜单时)更改了它的值)它们不会重新生成。
维护这些元素的正确方法是什么?
我在这些页面中搜索过 (msd, Whosebug1 Whosebug2 ) 但它只显示 "how to add" 而没有 "how to maintain" 控件
如果你能帮助我,下面是我的代码:
这是 aspx:
<asp:PlaceHolder ID="reportFields" runat="server"></asp:PlaceHolder>
这是后面的代码:
Private Sub generatenewReportField(count As Integer)
reportFields.Controls.Add(New LiteralControl("<div class=""col-sm-12"">"))
'Name field
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-3"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""txtNewFieldName" & count & """>Name</label>"))
Dim tx1 As New TextBox()
tx1.CssClass = "form-control input-sm"
tx1.ID = "txtNewFieldName" & count
tx1.ToolTip = "New Field Name"
reportFields.Controls.Add(tx1)
reportFields.Controls.Add(New LiteralControl("</div>"))
'formula field
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-3"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""txtNewFieldFormula" & count & """>Formula</label>"))
Dim tx2 As New TextBox()
tx2.CssClass = "form-control input-sm"
tx2.ID = "txtNewFieldFormula" & count
tx2.ToolTip = "New Field Formula"
reportFields.Controls.Add(tx2)
reportFields.Controls.Add(New LiteralControl("</div>"))
'isKPI?
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-2"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""chkKPI" & count & """>Is KPI</label><br/>"))
Dim isKPI As New CheckBox
isKPI.CssClass = " switch input-sm"
isKPI.ID = "chkKPI" & count
initializeSwitch()
reportFields.Controls.Add(isKPI)
reportFields.Controls.Add(New LiteralControl("</div>"))
'KPI Weight
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-3"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""txtNewFieldKPIWeight" & count & """>Weight</label>"))
Dim tx3 As New TextBox()
tx3.CssClass = "form-control input-sm"
tx3.ID = "txtNewFieldKPIWeight" & count
reportFields.Controls.Add(tx3)
reportFields.Controls.Add(New LiteralControl("</div>"))
reportFields.Controls.Add(New LiteralControl("</div>"))
reportFields.Controls.Add(New LiteralControl("<br/>"))
End Sub
感谢您的帮助!
您可以通过添加 部分回发 来解决问题,它只刷新页面的一部分。这样,您可以请求更新页面中需要更改的部分,并保留您不想要的部分。您可以使用 UpdatePanel 控件来做到这一点。
一些可以提供帮助的链接:
- 更新面板(MSDN):https://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel(v=vs.110).aspx
- UpdatePanel控件介绍:https://msdn.microsoft.com/en-us/library/bb399001.aspx
- 了解 ASP.NET AJAX 的部分页面更新:https://www.asp.net/web-forms/overview/older-versions-getting-started/aspnet-ajax/understanding-partial-page-updates-with-asp-net-ajax
我根据@Hammer125 的评论和我自己的研究找到了答案。
这都是关于使用 updatePanel 的。
link 应该对 msdn. Using update panel in aspx 有帮助。
我创建了两个更新面板。第一个是用户设置新元素值的地方,第二个是显示这些值的地方。出于我的目的,我在这里使用了一个 gridview 来显示和处理生成的值。然而,这个 gridview 可以被替换为任何想要的控件。此外,我还制作了一个具有我想要保存的属性的对象。
这是aspx。
<div class="col-md-12 well">
<asp:UpdatePanel ID="updPanelNewField" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div class="col-sm-12">
<div class="form-group col-sm-3">
<label for="txtNewName">Name</label>
<asp:TextBox runat="server" ID="txtNewName" CssClass="form-control input-sm" ToolTip="Field's name"></asp:TextBox>
</div>
<div class="form-group col-sm-3">
<label for="txtNewFormula">Formula</label>
<asp:TextBox runat="server" ID="txtNewFormula" CssClass="form-control input-sm" ToolTip="Field's formula"></asp:TextBox>
</div>
<div class="form-group col-sm-2">
<label for="chkNewKPI">is KPI</label><br />
<asp:CheckBox runat="server" ID="chkNewKPI" CssClass="input-sm"/>
</div>
<div class="form-group col-sm-3">
<label for="txtNewWeight">KPI Weight</label>
<asp:TextBox runat="server" ID="txtNewWeight" CssClass="form-control input-sm" ToolTip="KPI's Weight (Remember don't pass 100% ;) ) "></asp:TextBox>
</div>
<div class="form-group col-sm-1 text-center" style="padding-left:1em; padding-top:1em">
<asp:Button runat="server" ID="addNewField" CssClass="btn btn-primary" Width="2em" Height="2em" Text="+" Font-Bold="true" Font-Size="Large" />
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<hr />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gdvFields" runat="server" CellPadding="1" GridLines="Horizontal">
<Columns>
<asp:BoundField DataField ="Id" HeaderText="ID"/>
<asp:BoundField DataField="Name" HeaderText="Name"/>
<asp:BoundField DataField="Formula" HeaderText="Formula" />
<asp:CommandField HeaderText="Options" CausesValidation="true" ShowDeleteButton="true" ShowEditButton="true"/>
</Columns>
<PagerSettings PageButtonCount="10" />
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="addNewField" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
这是我在代码中添加的新 class:
<Serializable()> _
Public Class ReportField
Private _id As Integer
Private _name As String
Private _formula As String
Sub New(fieldId As Integer, fieldName As String, fieldFormula As String)
_id = fieldId
_name = fieldName
_formula = fieldFormula
End Sub
Public Property id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property formula() As String
Get
Return _formula
End Get
Set(ByVal value As String)
_formula = value
End Set
End Property
Private _isKPI As Boolean
Public Property isKPI() As Boolean
Get
Return _isKPI
End Get
Set(ByVal value As Boolean)
_isKPI = value
End Set
End Property
Private _KPIWeight As Integer
Public Property KPIWeight() As Integer
Get
Return _KPIWeight
End Get
Set(ByVal value As Integer)
_KPIWeight = value
End Set
End Property
End Class
这是我让它工作的背后代码:
#Region "Variables"
Dim count As Integer
Private thisReportFieldsList As List(Of ReportField)
#End Region
#Region "Events"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
If Not IsPostBack() Then
count = 1
thisReportFieldsList = New List(Of ReportField)
ViewState("reportFieldsList") = thisReportFieldsList
Else
thisReportFieldsList = CType(ViewState("reportFieldsList"), List(Of ReportField))
End If
gdvFields.DataSource = thisReportFieldsList
gdvFields.DataBind()
Catch ex As Exception
showError(ex.Message)
End Try
End Sub
Protected Sub addNewField_Click(sender As Object, e As EventArgs) Handles addNewField.Click
Try
If String.IsNullOrEmpty(txtNewName.Text) Or String.IsNullOrEmpty(txtNewFormula.Text) Then
showError("Please add at least the name and formula of the new field", "Field not added")
Return
End If
Dim id As Integer
If thisReportFieldsList.Count = 0 Then
id = 0
Else
id = thisReportFieldsList(thisReportFieldsList.Count - 1).id
End If
Dim fieldId As Integer = id + 1
Dim fieldName As String = Server.HtmlEncode(txtNewName.Text)
Dim fieldFormula As String = Server.HtmlEncode(txtNewFormula.Text)
txtNewName.Text = String.Empty
txtNewFormula.Text = String.Empty
thisReportFieldsList.Add(New ReportField(fieldId, fieldName, fieldFormula))
ViewState("reportFieldsList") = thisReportFieldsList
gdvFields.DataBind()
gdvFields.PageIndex = gdvFields.PageCount
Catch ex As Exception
showError(ex.Message)
End Try
End Sub
#End Region
我希望我已经很好地解释了自己,这对某人有帮助
甚至为您的页面调用 Pre_Init
中的 generateReportField()
方法。您需要在 每次 回发时执行此操作,因为每次回发都使用您页面的全新实例 class,并且您需要在 before ViewState 在 Init 阶段加载,否则 ViewState 将无法为这些控件正常工作。
我想在单击按钮时添加一组新的 .net 控件和 html 标记。
此时我有一个占位符,我在 VB.Net 中从后面的代码动态添加控件,这是正确的,但是,只要有回发(当单击按钮或下拉菜单时)更改了它的值)它们不会重新生成。 维护这些元素的正确方法是什么?
我在这些页面中搜索过 (msd, Whosebug1 Whosebug2 ) 但它只显示 "how to add" 而没有 "how to maintain" 控件 如果你能帮助我,下面是我的代码: 这是 aspx:
<asp:PlaceHolder ID="reportFields" runat="server"></asp:PlaceHolder>
这是后面的代码:
Private Sub generatenewReportField(count As Integer)
reportFields.Controls.Add(New LiteralControl("<div class=""col-sm-12"">"))
'Name field
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-3"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""txtNewFieldName" & count & """>Name</label>"))
Dim tx1 As New TextBox()
tx1.CssClass = "form-control input-sm"
tx1.ID = "txtNewFieldName" & count
tx1.ToolTip = "New Field Name"
reportFields.Controls.Add(tx1)
reportFields.Controls.Add(New LiteralControl("</div>"))
'formula field
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-3"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""txtNewFieldFormula" & count & """>Formula</label>"))
Dim tx2 As New TextBox()
tx2.CssClass = "form-control input-sm"
tx2.ID = "txtNewFieldFormula" & count
tx2.ToolTip = "New Field Formula"
reportFields.Controls.Add(tx2)
reportFields.Controls.Add(New LiteralControl("</div>"))
'isKPI?
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-2"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""chkKPI" & count & """>Is KPI</label><br/>"))
Dim isKPI As New CheckBox
isKPI.CssClass = " switch input-sm"
isKPI.ID = "chkKPI" & count
initializeSwitch()
reportFields.Controls.Add(isKPI)
reportFields.Controls.Add(New LiteralControl("</div>"))
'KPI Weight
reportFields.Controls.Add(New LiteralControl("<div class=""form-group col-sm-3"">"))
reportFields.Controls.Add(New LiteralControl("<label for=""txtNewFieldKPIWeight" & count & """>Weight</label>"))
Dim tx3 As New TextBox()
tx3.CssClass = "form-control input-sm"
tx3.ID = "txtNewFieldKPIWeight" & count
reportFields.Controls.Add(tx3)
reportFields.Controls.Add(New LiteralControl("</div>"))
reportFields.Controls.Add(New LiteralControl("</div>"))
reportFields.Controls.Add(New LiteralControl("<br/>"))
End Sub
感谢您的帮助!
您可以通过添加 部分回发 来解决问题,它只刷新页面的一部分。这样,您可以请求更新页面中需要更改的部分,并保留您不想要的部分。您可以使用 UpdatePanel 控件来做到这一点。
一些可以提供帮助的链接:
- 更新面板(MSDN):https://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel(v=vs.110).aspx
- UpdatePanel控件介绍:https://msdn.microsoft.com/en-us/library/bb399001.aspx
- 了解 ASP.NET AJAX 的部分页面更新:https://www.asp.net/web-forms/overview/older-versions-getting-started/aspnet-ajax/understanding-partial-page-updates-with-asp-net-ajax
我根据@Hammer125 的评论和我自己的研究找到了答案。 这都是关于使用 updatePanel 的。 link 应该对 msdn. Using update panel in aspx 有帮助。
我创建了两个更新面板。第一个是用户设置新元素值的地方,第二个是显示这些值的地方。出于我的目的,我在这里使用了一个 gridview 来显示和处理生成的值。然而,这个 gridview 可以被替换为任何想要的控件。此外,我还制作了一个具有我想要保存的属性的对象。
这是aspx。
<div class="col-md-12 well">
<asp:UpdatePanel ID="updPanelNewField" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div class="col-sm-12">
<div class="form-group col-sm-3">
<label for="txtNewName">Name</label>
<asp:TextBox runat="server" ID="txtNewName" CssClass="form-control input-sm" ToolTip="Field's name"></asp:TextBox>
</div>
<div class="form-group col-sm-3">
<label for="txtNewFormula">Formula</label>
<asp:TextBox runat="server" ID="txtNewFormula" CssClass="form-control input-sm" ToolTip="Field's formula"></asp:TextBox>
</div>
<div class="form-group col-sm-2">
<label for="chkNewKPI">is KPI</label><br />
<asp:CheckBox runat="server" ID="chkNewKPI" CssClass="input-sm"/>
</div>
<div class="form-group col-sm-3">
<label for="txtNewWeight">KPI Weight</label>
<asp:TextBox runat="server" ID="txtNewWeight" CssClass="form-control input-sm" ToolTip="KPI's Weight (Remember don't pass 100% ;) ) "></asp:TextBox>
</div>
<div class="form-group col-sm-1 text-center" style="padding-left:1em; padding-top:1em">
<asp:Button runat="server" ID="addNewField" CssClass="btn btn-primary" Width="2em" Height="2em" Text="+" Font-Bold="true" Font-Size="Large" />
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<hr />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gdvFields" runat="server" CellPadding="1" GridLines="Horizontal">
<Columns>
<asp:BoundField DataField ="Id" HeaderText="ID"/>
<asp:BoundField DataField="Name" HeaderText="Name"/>
<asp:BoundField DataField="Formula" HeaderText="Formula" />
<asp:CommandField HeaderText="Options" CausesValidation="true" ShowDeleteButton="true" ShowEditButton="true"/>
</Columns>
<PagerSettings PageButtonCount="10" />
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="addNewField" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
这是我在代码中添加的新 class:
<Serializable()> _
Public Class ReportField
Private _id As Integer
Private _name As String
Private _formula As String
Sub New(fieldId As Integer, fieldName As String, fieldFormula As String)
_id = fieldId
_name = fieldName
_formula = fieldFormula
End Sub
Public Property id() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property formula() As String
Get
Return _formula
End Get
Set(ByVal value As String)
_formula = value
End Set
End Property
Private _isKPI As Boolean
Public Property isKPI() As Boolean
Get
Return _isKPI
End Get
Set(ByVal value As Boolean)
_isKPI = value
End Set
End Property
Private _KPIWeight As Integer
Public Property KPIWeight() As Integer
Get
Return _KPIWeight
End Get
Set(ByVal value As Integer)
_KPIWeight = value
End Set
End Property
End Class
这是我让它工作的背后代码:
#Region "Variables"
Dim count As Integer
Private thisReportFieldsList As List(Of ReportField)
#End Region
#Region "Events"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
If Not IsPostBack() Then
count = 1
thisReportFieldsList = New List(Of ReportField)
ViewState("reportFieldsList") = thisReportFieldsList
Else
thisReportFieldsList = CType(ViewState("reportFieldsList"), List(Of ReportField))
End If
gdvFields.DataSource = thisReportFieldsList
gdvFields.DataBind()
Catch ex As Exception
showError(ex.Message)
End Try
End Sub
Protected Sub addNewField_Click(sender As Object, e As EventArgs) Handles addNewField.Click
Try
If String.IsNullOrEmpty(txtNewName.Text) Or String.IsNullOrEmpty(txtNewFormula.Text) Then
showError("Please add at least the name and formula of the new field", "Field not added")
Return
End If
Dim id As Integer
If thisReportFieldsList.Count = 0 Then
id = 0
Else
id = thisReportFieldsList(thisReportFieldsList.Count - 1).id
End If
Dim fieldId As Integer = id + 1
Dim fieldName As String = Server.HtmlEncode(txtNewName.Text)
Dim fieldFormula As String = Server.HtmlEncode(txtNewFormula.Text)
txtNewName.Text = String.Empty
txtNewFormula.Text = String.Empty
thisReportFieldsList.Add(New ReportField(fieldId, fieldName, fieldFormula))
ViewState("reportFieldsList") = thisReportFieldsList
gdvFields.DataBind()
gdvFields.PageIndex = gdvFields.PageCount
Catch ex As Exception
showError(ex.Message)
End Try
End Sub
#End Region
我希望我已经很好地解释了自己,这对某人有帮助
甚至为您的页面调用 Pre_Init
中的 generateReportField()
方法。您需要在 每次 回发时执行此操作,因为每次回发都使用您页面的全新实例 class,并且您需要在 before ViewState 在 Init 阶段加载,否则 ViewState 将无法为这些控件正常工作。