持久化动态生成的控件.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 控件来做到这一点。

一些可以提供帮助的链接:

我根据@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 将无法为这些控件正常工作。