ASP.NET - 在运行时向转发器添加行

发布于 2024-11-18 12:42:56 字数 1948 浏览 4 评论 0原文

Public Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Page.IsPostBack = False Then
            Dim ds1 As New List(Of Link)

            For i = 1 To x
                Dim h As New Link
                ds1.Add(h)
                h.Text = "ssss"
                h.URL = "yyyyy"
            Next

            rptMenu.DataSource = (ds1)
        Else
            rptMenu.DataSource = ViewState("ds1")
        End If

        rptMenu.DataBind()
    End Sub

    Protected Sub addFeild()

        Dim ds1 As List(Of Link) = rptMenu.DataSource
        Dim h As New Link
        ds1.Add(H)
        rptMenu.DataBind()
    End Sub

    Private Sub Menu_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
        ViewState("ds1") = rptMenu.DataSource
    End Sub
End Class


 <asp:Repeater ID="rptMenu" runat="server">
        <ItemTemplate>
            <tr>
                <td><asp:TextBox CssClass="txtBox" ID="txtText" runat="server" Text='<%# Eval("Text") %>'></asp:TextBox></td>
                <td><asp:TextBox CssClass="txtBox" ID="txtLocation" runat="server" Text='<%# Eval("URL") %>'></asp:TextBox></td>
                <td><asp:Button ID="btnDelete" runat="server" Text="Delete" /></td>
            </tr>
        </ItemTemplate>
        <FooterTemplate>
            <tr><td colspan="3">
                <asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="addFeild" />
            </td></tr></table>
        </FooterTemplate>
    </asp:Repeater>



此代码在我单击添加时添加行,

但是,它会删除所有更改。

如何在不删除更改的情况下向转发器添加行?

Public Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Page.IsPostBack = False Then
            Dim ds1 As New List(Of Link)

            For i = 1 To x
                Dim h As New Link
                ds1.Add(h)
                h.Text = "ssss"
                h.URL = "yyyyy"
            Next

            rptMenu.DataSource = (ds1)
        Else
            rptMenu.DataSource = ViewState("ds1")
        End If

        rptMenu.DataBind()
    End Sub

    Protected Sub addFeild()

        Dim ds1 As List(Of Link) = rptMenu.DataSource
        Dim h As New Link
        ds1.Add(H)
        rptMenu.DataBind()
    End Sub

    Private Sub Menu_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
        ViewState("ds1") = rptMenu.DataSource
    End Sub
End Class

 <asp:Repeater ID="rptMenu" runat="server">
        <ItemTemplate>
            <tr>
                <td><asp:TextBox CssClass="txtBox" ID="txtText" runat="server" Text='<%# Eval("Text") %>'></asp:TextBox></td>
                <td><asp:TextBox CssClass="txtBox" ID="txtLocation" runat="server" Text='<%# Eval("URL") %>'></asp:TextBox></td>
                <td><asp:Button ID="btnDelete" runat="server" Text="Delete" /></td>
            </tr>
        </ItemTemplate>
        <FooterTemplate>
            <tr><td colspan="3">
                <asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="addFeild" />
            </td></tr></table>
        </FooterTemplate>
    </asp:Repeater>

This code adds row whin i click Add

However, it removes all changes.

How can I add rows to repeater without removing changes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

负佳期 2024-11-25 12:42:56

为了解决这个问题,我使用 Reflector 来确认 Repeater 在处理添加行本身时所做的事情,创建一个继承自 RepeaterExtensibleRepeater并允许为每次更新添加一行。它唯一的问题是您无法使用页脚概念,因为更新时页脚后面会出现添加的行。

通过将相关 RepeaterItemVisible 设置为 False 来处理删除行。

IIRC 您在回调时丢失数据的原因是因为您甚至在回调时调用 DataBind,这会重置所有现有数据,包括用户表单数据。

该代码是专有的,但由于它基于 Reflector 对 .NET 2.0 Repeater 的显示,我可以向您展示编辑后的版本:

Imports System.ComponentModel
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

'''======================================================================
''' Class: ExtensibleRepeater
''' 
''' <summary>
'''   A <see cref="Repeater" /> that can be extended by one item.
''' </summary>
''' 
''' <remarks>
'''   BUG: If the <see cref="ExtensibleRepeater.FooterTemplate" /> is defined, the additional
'''  item will appear after it!
''' </remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created based upon reflection on Repeater.
''' </revisionhistory>
'''======================================================================
<snip>
Public Class ExtensibleRepeater
    Inherits Repeater

Private additionalItem As RepeaterItem
<snip>

'''---------------------------------------------------------------------
''' Function: AddNew
''' 
''' <summary>
'''   Adds another <see cref="RepeaterItem"></see> to the <see cref="ExtensibleRepeater"></see>.
''' </summary>
''' 
''' <param name="ItemData">
'''   The data item to associate with the <see cref="RepeaterItem"></see>.
'''  Ignored if <paramref name="UseDataSource"></paramref> is False.
''' </param>
''' <param name="UseDataSource">
'''   Indicates whether to use the specified data source.
''' </param>
''' 
''' <returns>The new <see cref="System.Web.UI.WebControls.RepeaterItem"></see>.</returns>
''' 
''' <exception cref="NotSupportedException">Called more than once.</exception>
''' 
''' <remarks>
'''   Currently can only be called once. Must be called again after
'''  <see cref="DataBind"></see> is called to recreate the additional item.
''' </remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created based upon reflection on the protected Repeater.CreateControlHierarchy.
''' </revisionhistory>
'''---------------------------------------------------------------------
Public Function AddNew(ByVal ItemData As Object, Optional ByVal UseDataSource As Boolean = True) As RepeaterItem

<snip>
    If additionalItem IsNot Nothing Then _
        Throw New NotSupportedException

<snip>
    additionalItem = CreateItem(dataItemCount, itemType, UseDataSource, ItemData)

<snip>
    Return additionalItem
End Function

'''---------------------------------------------------------------------
''' Property: Items
''' 
''' <summary>
'''   Gets a collection of <see cref="System.Web.UI.WebControls.RepeaterItem"></see>
'''  objects in the <see cref="ExtensibleRepeater"></see>.
''' </summary>
''' 
''' <returns>
'''   A collection of <see cref="System.Web.UI.WebControls.RepeaterItem"></see>
'''  objects. The default is an empty <see cref="System.Web.UI.WebControls.RepeaterItemCollection"></see>.
''' </returns>
''' 
''' <remarks></remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created.
''' </revisionhistory>
'''---------------------------------------------------------------------
<snip>
Public Overrides ReadOnly Property Items() As RepeaterItemCollection
    Get
        If additionalItem IsNot Nothing Then
            Dim newItems As New ArrayList(MyBase.Items)
            newItems.Add(additionalItem)
            Return New RepeaterItemCollection(newItems)
        End If
        Return MyBase.Items
    End Get
End Property

'''---------------------------------------------------------------------
''' Function: CreateItem
''' 
''' <summary>
'''   Creates a <see cref="System.Web.UI.WebControls.RepeaterItem"></see>
'''  with the specified item type and location within the <see cref="ExtensibleRepeater"></see>.
''' </summary>
''' 
''' <param name="ItemIndex">
'''   The specified location within the <see cref="ExtensibleRepeater"></see>
'''  to place the created item.
''' </param>
''' <param name="ItemType">
'''   A <see cref="System.Web.UI.WebControls.ListItemType"></see> that
'''  represents the specified type of the <see cref="T:System.Web.UI.WebControls.Repeater"></see>
'''  item to create.
''' </param>
''' <param name="DataBind">
'''   Indicates whether to use the specified data source.
''' </param>
''' <param name="DataItem">
'''   The data item to associate with the <see cref="RepeaterItem"></see>.
'''  Ignored if <paramref name="DataBind"></paramref> is False.
''' </param>
''' 
''' <returns>The new <see cref="System.Web.UI.WebControls.RepeaterItem"></see>.</returns>
''' 
''' <remarks></remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created from reflection on the private Repeater.CreateItem, with no changes.
''' </revisionhistory>
'''---------------------------------------------------------------------
Private Overloads Function CreateItem(ByVal ItemIndex As Integer, ByVal ItemType As ListItemType, ByVal DataBind As Boolean, ByVal DataItem As Object) As RepeaterItem
<snip>

'''---------------------------------------------------------------------
''' Property: FooterTemplate
''' 
''' <summary>
'''   Gets or sets the <see cref="System.Web.UI.ITemplate" /> that
'''  defines how the footer section of the <see cref="ExtensibleRepeater" />
'''  control is displayed.
''' </summary>
''' 
''' <value>
'''   A <see cref="System.Web.UI.ITemplate" /> that defines how the
'''  footer section of the <see cref="ExtensibleRepeater" /> control is
'''  displayed.
'''   The default value is Nothing.
''' </value>
''' 
''' <remarks>
'''   This property does not change the inherited behaviour. It is
'''  only overridden to highlight this missing feature:
'''   TODO: BUG: This will appear before an additional item if one is added.
''' </remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created.
''' </revisionhistory>
'''---------------------------------------------------------------------
<Obsolete("BUG: This will appear before an additional item if one is added.")> _
<Description("The template used for the footer. BUG: This will appear before an additional item if one is added."), _
 Browsable(False), DefaultValue(CStr(Nothing)), _
 PersistenceMode(PersistenceMode.InnerProperty), _
 TemplateContainer(GetType(RepeaterItem))> _
Public Overrides Property FooterTemplate() As ITemplate
<snip>

'''---------------------------------------------------------------------
''' Sub: DataBind
''' 
''' <summary>
'''   Binds the <see cref="ExtensibleRepeater"></see> control and all
'''  its child controls to the specified data source.
''' </summary>
''' 
''' <remarks>
'''   <see cref="AddNew"></see> must be called again to restore the
'''  additional item if it is needed.
''' </remarks>
''' 
''' <revisionhistory>
'''   100908 MEH Created.
''' </revisionhistory>
'''---------------------------------------------------------------------
Overrides Sub DataBind()
    additionalItem = Nothing
<snip>

End Class

To solve this issue I used Reflector to confirm what was done by the Repeater when it handles adding rows itself, creating an ExtensibleRepeater that inherits from Repeater and allows one row to be added for each update. Its only issue is you can't use the footer concept because an added row appears after the footer when it is updated.

Deleting a row is handled by setting the relevant RepeaterItem's Visible to False.

IIRC the reason why you're losing data on callback is because you're calling DataBind even on callback, which resets all existing data, including user form data.

The code is proprietary, but as it is based upon Reflector's display of the .NET 2.0 Repeater, I can show you an edited version:

Imports System.ComponentModel
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

'''======================================================================
''' Class: ExtensibleRepeater
''' 
''' <summary>
'''   A <see cref="Repeater" /> that can be extended by one item.
''' </summary>
''' 
''' <remarks>
'''   BUG: If the <see cref="ExtensibleRepeater.FooterTemplate" /> is defined, the additional
'''  item will appear after it!
''' </remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created based upon reflection on Repeater.
''' </revisionhistory>
'''======================================================================
<snip>
Public Class ExtensibleRepeater
    Inherits Repeater

Private additionalItem As RepeaterItem
<snip>

'''---------------------------------------------------------------------
''' Function: AddNew
''' 
''' <summary>
'''   Adds another <see cref="RepeaterItem"></see> to the <see cref="ExtensibleRepeater"></see>.
''' </summary>
''' 
''' <param name="ItemData">
'''   The data item to associate with the <see cref="RepeaterItem"></see>.
'''  Ignored if <paramref name="UseDataSource"></paramref> is False.
''' </param>
''' <param name="UseDataSource">
'''   Indicates whether to use the specified data source.
''' </param>
''' 
''' <returns>The new <see cref="System.Web.UI.WebControls.RepeaterItem"></see>.</returns>
''' 
''' <exception cref="NotSupportedException">Called more than once.</exception>
''' 
''' <remarks>
'''   Currently can only be called once. Must be called again after
'''  <see cref="DataBind"></see> is called to recreate the additional item.
''' </remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created based upon reflection on the protected Repeater.CreateControlHierarchy.
''' </revisionhistory>
'''---------------------------------------------------------------------
Public Function AddNew(ByVal ItemData As Object, Optional ByVal UseDataSource As Boolean = True) As RepeaterItem

<snip>
    If additionalItem IsNot Nothing Then _
        Throw New NotSupportedException

<snip>
    additionalItem = CreateItem(dataItemCount, itemType, UseDataSource, ItemData)

<snip>
    Return additionalItem
End Function

'''---------------------------------------------------------------------
''' Property: Items
''' 
''' <summary>
'''   Gets a collection of <see cref="System.Web.UI.WebControls.RepeaterItem"></see>
'''  objects in the <see cref="ExtensibleRepeater"></see>.
''' </summary>
''' 
''' <returns>
'''   A collection of <see cref="System.Web.UI.WebControls.RepeaterItem"></see>
'''  objects. The default is an empty <see cref="System.Web.UI.WebControls.RepeaterItemCollection"></see>.
''' </returns>
''' 
''' <remarks></remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created.
''' </revisionhistory>
'''---------------------------------------------------------------------
<snip>
Public Overrides ReadOnly Property Items() As RepeaterItemCollection
    Get
        If additionalItem IsNot Nothing Then
            Dim newItems As New ArrayList(MyBase.Items)
            newItems.Add(additionalItem)
            Return New RepeaterItemCollection(newItems)
        End If
        Return MyBase.Items
    End Get
End Property

'''---------------------------------------------------------------------
''' Function: CreateItem
''' 
''' <summary>
'''   Creates a <see cref="System.Web.UI.WebControls.RepeaterItem"></see>
'''  with the specified item type and location within the <see cref="ExtensibleRepeater"></see>.
''' </summary>
''' 
''' <param name="ItemIndex">
'''   The specified location within the <see cref="ExtensibleRepeater"></see>
'''  to place the created item.
''' </param>
''' <param name="ItemType">
'''   A <see cref="System.Web.UI.WebControls.ListItemType"></see> that
'''  represents the specified type of the <see cref="T:System.Web.UI.WebControls.Repeater"></see>
'''  item to create.
''' </param>
''' <param name="DataBind">
'''   Indicates whether to use the specified data source.
''' </param>
''' <param name="DataItem">
'''   The data item to associate with the <see cref="RepeaterItem"></see>.
'''  Ignored if <paramref name="DataBind"></paramref> is False.
''' </param>
''' 
''' <returns>The new <see cref="System.Web.UI.WebControls.RepeaterItem"></see>.</returns>
''' 
''' <remarks></remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created from reflection on the private Repeater.CreateItem, with no changes.
''' </revisionhistory>
'''---------------------------------------------------------------------
Private Overloads Function CreateItem(ByVal ItemIndex As Integer, ByVal ItemType As ListItemType, ByVal DataBind As Boolean, ByVal DataItem As Object) As RepeaterItem
<snip>

'''---------------------------------------------------------------------
''' Property: FooterTemplate
''' 
''' <summary>
'''   Gets or sets the <see cref="System.Web.UI.ITemplate" /> that
'''  defines how the footer section of the <see cref="ExtensibleRepeater" />
'''  control is displayed.
''' </summary>
''' 
''' <value>
'''   A <see cref="System.Web.UI.ITemplate" /> that defines how the
'''  footer section of the <see cref="ExtensibleRepeater" /> control is
'''  displayed.
'''   The default value is Nothing.
''' </value>
''' 
''' <remarks>
'''   This property does not change the inherited behaviour. It is
'''  only overridden to highlight this missing feature:
'''   TODO: BUG: This will appear before an additional item if one is added.
''' </remarks>
''' 
''' <revisionhistory>
'''   100907 MEH Created.
''' </revisionhistory>
'''---------------------------------------------------------------------
<Obsolete("BUG: This will appear before an additional item if one is added.")> _
<Description("The template used for the footer. BUG: This will appear before an additional item if one is added."), _
 Browsable(False), DefaultValue(CStr(Nothing)), _
 PersistenceMode(PersistenceMode.InnerProperty), _
 TemplateContainer(GetType(RepeaterItem))> _
Public Overrides Property FooterTemplate() As ITemplate
<snip>

'''---------------------------------------------------------------------
''' Sub: DataBind
''' 
''' <summary>
'''   Binds the <see cref="ExtensibleRepeater"></see> control and all
'''  its child controls to the specified data source.
''' </summary>
''' 
''' <remarks>
'''   <see cref="AddNew"></see> must be called again to restore the
'''  additional item if it is needed.
''' </remarks>
''' 
''' <revisionhistory>
'''   100908 MEH Created.
''' </revisionhistory>
'''---------------------------------------------------------------------
Overrides Sub DataBind()
    additionalItem = Nothing
<snip>

End Class
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文