当我的Gridview绑定了"几行"对于数据,我目前添加新行的方法是一个适当的设计并且可以正常运行。#34;。但是,如果与"许多行绑定"对于数据,我目前添加新行的方法存在缺陷:我使用的 EmptyDataTemplate 是使用 FooterTemplate 公开的。因此,如果我有3行数据并单击"添加新记录",则网格将重新显示第4行全部"准备好"用于数据输入。然而,如果我有30行,要插入的行的显示是如此之下,它需要滚动。
Protected Sub AddNewRecord(ByVal sender As Object, ByVal e As EventArgs)
GridView1.ShowFooter = True
'rebind data so GridView1_RowDataBound gets a chance to populate the footer
iSubscriberID = Session("SubscriberID")
LoadDataGrid(iSubscriberID)
End Sub
我希望能够改进添加新行的操作但仍然使用FooterTemplate。
是否有任何代码可以添加到我的 GridView1_RowDataBound 处理程序中以隐藏现有数据行,但仍然通过FooterTemplate公开EmptyDataTemplate以便插入?我曾尝试过在那里破解一些没有成功的事情。这是我现有的处理程序代码:
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) _
Handles GridView1.RowDataBound
'-------------------------------------------------------------------------------------------*
' Handle 'Insert' requirements:
' - Bind dropdownlist controls with the possible incumbents and backups for some new position
'-------------------------------------------------------------------------------------------*
If e.Row.RowType = DataControlRowType.Footer Then
' Finding the Dropdown control.
Dim ctrl As Control = e.Row.FindControl("ddlUsers")
If ctrl IsNot Nothing Then
Dim dd As DropDownList = TryCast(ctrl, DropDownList)
dd.DataSource = allUsers
dd.DataBind()
End If
Dim ctrlB As Control = e.Row.FindControl("ddlUsersBackup")
If ctrlB IsNot Nothing Then
Dim ddB As DropDownList = TryCast(ctrlB, DropDownList)
ddB.DataSource = allUsers
ddB.DataBind()
End If
End If
End Sub
我对所有列使用 TemplateField 定义;这是一个显示 FooterTemplate 的一部分的示例:
<asp:TemplateField HeaderText="Incumbent">
<ItemTemplate>
<asp:Label ID="lblUser" runat="server" Text='<%# Eval("Incumbent")%>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:Label ID="lblUser" runat="server" Text='<%# Eval("Incumbent")%>' Visible = "false"></asp:Label>
<asp:DropDownList Width="100%" runat="server"
id="ddlUsers" AutoPostBack="true"
DataTextField="FullName" DataValueField="UserID"
OnSelectedIndexChanged="ddlUsers_SelectedIndexChanged">
</asp:DropDownList>
</EditItemTemplate>
<FooterTemplate>
<asp:Label ID="lblUser" runat="server" Text='Set Incumbent'></asp:Label>
<br />
<asp:DropDownList Width="100%" runat="server"
id="ddlUsers" AutoPostBack="true"
DataTextField="FullName" DataValueField="UserID"
OnSelectedIndexChanged="ddlUsers_SelectedIndexChanged">
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
我可能有用的另一个想法是将页面滚动到底部,以便&#34;插入&#34;使用ShowFooter = True重新填充gridview时,该行始终可见。但是,这似乎涉及一些我更喜欢在此页面上避免使用的Javascript。
编辑:2016年2月18日 - 尝试将分页添加到Gridview - 一个新的复杂功能
@Lesmian - 按照你的建议添加一个寻呼机很简单,但现在它完全打破了Gridview:
我研究了这个错误,我不明白为什么我的强势类型的Positions集合不能支持分页;这是为Gridview实例化我的数据源的代码:
Public Class Positions
Implements IEnumerable(Of Position)
Public List As New List(Of Position)
Public Function GetEnumerator() As IEnumerator(Of Position) _
Implements IEnumerable(Of Position).GetEnumerator
Return List.GetEnumerator()
End Function
Private Function GetEnumerator1() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return List.GetEnumerator()
End Function
Public Sub New(ByVal subscriberID As Integer, Optional ByVal filterOnUserID As Integer = 0)
Dim sConnDatabase As String = ConfigurationManager.ConnectionStrings("DatabaseConnString").ConnectionString
Dim connection As New SqlConnection(sConnDatabase)
Dim cmd As SqlCommand
Try
cmd = New SqlCommand("dbo.GetPositionsBySubscriberID", connection)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@SubscriberID", subscriberID)
cmd.Parameters.AddWithValue("@UserID", filterOnUserID) 'non-zero UserID returns only positions where User is Incumbent or Backup
connection.Open()
Dim objReader As SqlDataReader = cmd.ExecuteReader()
Do While objReader.Read()
Dim p As Position = New Position(objReader)
List.Add(p)
Loop
objReader.Close()
connection.Close()
添加寻呼机来解决原始问题的方法已经开辟了一个新问题。有什么想法?
答案 0 :(得分:2)
OP中的实际问题似乎归结为“回发后如何保留插入视图的行”。
Page
对象已经有一个名为Focus
的方法,可用于在页面呈现完成后使特定控件获得焦点。
当浏览器可见区域之外的控件获得焦点时,浏览器会将该控件滚动到视图中,以便用户可以看到焦点。
因此,为了使插入行可见,只需确保在后面的代码中将其设置为可见时,将焦点设置在行中的适当控件上。
答案 1 :(得分:0)
滚动gridview需要javascript,但如果你不想使用它,也许其他方法将适合你的需求。如果您向网格视图添加寻呼机并在每页设置少量项目,则添加新项目不会导致滚动条出现。使用这种方法我们有另外一个缺陷 - 新项目可能出现在新页面上,因此您应该强制网格显示最后一页,然后新行将始终可见:
Protected Sub GridView1_RowCommand(sender As Object, e As GridViewCommandEventArgs) _
Handles GridView1.RowCommand
' Insert data if the CommandName == "Insert"
' and the validation controls indicate valid data...
If e.CommandName = "Insert" AndAlso Page.IsValid Then
' Insert new record
GridView1DataSource.Insert()
' Indicate that the user needs to be sent to the last page
SendUserToLastPage = True
End If
End Sub
Protected Sub GridView1_DataBound(sender As Object, e As EventArgs) _
Handles GridView1.DataBound
' Send user to last page of data, if needed
If SendUserToLastPage Then
GridView1.PageIndex = GridView1.PageCount - 1
End If
End Sub
您可以在此找到此方法的完整示例:http://www.asp.net/web-forms/overview/data-access/enhancing-the-gridview/inserting-a-new-record-from-the-gridview-s-footer-vb
编辑:2016年2月18日 - 数据源不支持服务器端数据分页错误
您的自定义集合必须实现ICollection接口才能使用GridView服务器端分页。 IEnumerable并没有实现ICollection,这就是你得到错误的原因。有关在vb中实现的示例,您可以阅读:https://support.microsoft.com/en-us/kb/306961和此:http://www.codeproject.com/Articles/265692/Having-fun-with-custom-collections。之后,GridView应该为您完成剩下的工作。
答案 2 :(得分:0)
总体思路:
1.将GridView放置在固定高度的可滚动div中
2.在div位置单行表下方,您需要插入新记录和&#34;添加&#34;按钮
3.如果可能,使用SqlDataSource填充GridView并将insert命令包含到SqlDataSource中
4.在InsertParameters块中,使用asp:controlParameter绑定到新值
5.将代码添加到Add_Click处理程序
mySqlDataSource.Insert()
PS:更好的是,将GridView重写为ListView(由.NET 3.5支持)。这将为您提供更多灵活性。例如,您可以将insert插入第一行。