Additional Repeater questions for Steven Cheng

M

Mark

I am trying to use a Pagable Repeater with checkboxes in ASP.Net, I cannot
seem to associate the checkbox with a particular database record so I lose
the checked state from page-to-page.
Below is a sample 1-page ASP.Net apllication built to run against the SQL
pubs database.
There are contents of 2 files
1. ASPX,
2. ASPX.VB

If there is anyway you can help, I'd really appreciate it.

Thank you,
Mark Christy


ASPX file.

<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="frmRepeater.aspx.vb" Inherits="Repeater.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>WebForm1</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server" onload="OnRefresh">
<table border="0">
<tr>
<td>
<asp:Button id="btnSelectAll" runat="server" Text="Select
All"></asp:Button>
</td>
<td>
<asp:Button id="btnClearAll" runat="server" Text="Clear
All"></asp:Button>
</td>
<td>
Page:
<asp:Label id="CurrentPage" runat="server"></asp:Label></td>
<td>
<asp:linkbutton runat="server" text="Previous"
onclick="OnPreviousPage" ID="Linkbutton1" NAME="Linkbutton1" />
</td>
<td>
<asp:linkbutton runat="server" text="Next" onclick="OnNextPage"
ID="Linkbutton2" NAME="Linkbutton2" />
</td>
</tr>
</table>
<br>
<br>
<table border="0">
<tr>
<asp:Repeater id="Repeater1" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<span style="display:none;">
<%# FindCheckBox(Container,Container.DataItem) %>
</span>
<td>
<asp:checkbox runat="server" id="ckSelected" AutoPostBack="false" />
</td>
<%# ShowRow(Container.DataItem) %>
</ItemTemplate>
<SeparatorTemplate>
<tr>
<td colspan="3"><hr>
</td>
</tr>
</SeparatorTemplate>
<FooterTemplate>
<tr>
<td colspan="3"><hr>
</td>
</FooterTemplate>
</asp:Repeater>
</tr>
</table>
</form>
</body>
</HTML>

ASPX.VB file.

Public Class WebForm1
Inherits System.Web.UI.Page
Public PageSize As Integer = 3

#Region " Web Form Designer Generated Code "

'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Public Sub
InitializeComponent()

End Sub
Protected WithEvents Repeater1 As System.Web.UI.WebControls.Repeater
Protected WithEvents btnSelectAll As System.Web.UI.WebControls.Button
Protected WithEvents btnClearAll As System.Web.UI.WebControls.Button
Protected WithEvents CurrentPage As System.Web.UI.WebControls.Label
Protected WithEvents Linkbutton1 As System.Web.UI.WebControls.LinkButton
Protected WithEvents Linkbutton2 As System.Web.UI.WebControls.LinkButton

'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Public designerPlaceholderDeclaration As System.Object

Public Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub

#End Region

Public Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not (IsPostBack) Then
LoadData()
End If

Dim data As DataTable = Session("SearchResults")
Repeater1.DataSource = data
Repeater1.DataBind()

End Sub

Public Function LoadData() As DataTable
Dim qry As String

qry = "select pub_name, (city + ' ' + state) as pub_addr"
qry &= " from publishers"
Dim da As SqlClient.SqlDataAdapter = New
SqlClient.SqlDataAdapter(qry,
Convert.ToString(ConfigurationSettings.AppSettings("dbConnString")))
Dim data As DataTable = New DataTable

' Fill the datatable using the database query
Try
da.Fill(data)
Session("SearchResults") = data

Catch ex As Exception
Session("SearchResults") = Nothing
data = Nothing
End Try

Return data
End Function

Public Function FindCheckBox(ByVal container As Control, ByVal dataItem
As Object) As CheckBox
On Error Resume Next

Dim ctl As CheckBox = CType(container.FindControl("ckSelected"),
CheckBox)

If ctl Is Nothing Then
Return Nothing
Else
ctl.Checked = Page.Request.Form(ctl.UniqueID) = "on"
Return ctl

End If
End Function

Public Function ShowRow(ByVal dataItem As Object) As String
On Error Resume Next
Dim _output As String
Dim _row As DataRowView = CType(dataItem, DataRowView)
_output = "<td>" & _row("pub_name") & "</td></tr>"
_output &= "<tr>"
_output &= "<td colspan=2>" & _row("pub_addr") & "</td>"
_output &= "</tr>"

Return _output
End Function

Public Sub btnSelectAll_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnSelectAll.Click

' Select all in the repeater
On Error Resume Next
Dim i As Integer

For i = 0 To Repeater1.Items.Count - 1
Dim CurrentCheckBox As CheckBox =
CType(Repeater1.Items(i).FindControl("ckSelected"), WebControls.CheckBox)
CurrentCheckBox.Checked = True
Next

End Sub

Public Sub btnClearAll_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnClearAll.Click
On Error Resume Next
Dim i As Integer

' Clear all in the repeater
For i = 0 To Repeater1.Items.Count - 1
Dim CurrentCheckBox As CheckBox =
CType(Repeater1.Items(i).FindControl("ckSelected"), WebControls.CheckBox)
CurrentCheckBox.Checked = False
Next

End Sub

Public Property CurrentPageIndex() As Integer
Get
Return ViewState("CurrentPageIndex")
End Get

Set(ByVal value As Integer)
ViewState("CurrentPageIndex") = value
End Set
End Property



Public Sub Refresh()
CurrentPage.Text = (CurrentPageIndex + 1).ToString()
Repeater1.DataSource = GetPage(Nothing, 0)
Repeater1.DataBind()
End Sub

Public Sub OnRefresh(ByVal sender As Object, ByVal e As EventArgs)
Refresh()
End Sub

Public Sub OnPreviousPage(ByVal sender As Object, ByVal e As EventArgs)
CurrentPageIndex -= 1
RefreshPage()
End Sub

Public Sub OnNextPage(ByVal sender As Object, ByVal e As EventArgs)
CurrentPageIndex += 1
RefreshPage()
End Sub

Public Sub RefreshPage()
Dim _data As DataTable = Session("SearchResults")
AdjustPageIndex(_data.Rows.Count)

CurrentPage.Text = (CurrentPageIndex + 1).ToString()
Repeater1.DataSource = GetPage(_data, CurrentPageIndex)
Repeater1.DataBind()
End Sub

Public Function GetData() As DataTable
Dim _data As DataTable = CType(Session("SearchResults"), DataTable)
If _data Is Nothing Then
_data = LoadData()
End If

Return _data
End Function

Public Sub AdjustPageIndex(ByVal rowCount As Integer)
Dim pageCount As Integer
pageCount = rowCount \ PageSize ' \ truncates while / not
If pageCount Mod PageSize > 0 Then
pageCount += 1
End If

CurrentPageIndex = IIf(CurrentPageIndex < 0, 0, CurrentPageIndex)
CurrentPageIndex = IIf(CurrentPageIndex > pageCount - 1, pageCount -
1, CurrentPageIndex)
End Sub

Public Function GetPage(ByVal dt As DataTable, ByVal pageIndex As
Integer) As Object
If dt Is Nothing Then
dt = LoadData()
End If

Dim firstIndexInPage As Integer = (CurrentPageIndex * PageSize)
Dim rows As DataRowCollection = dt.Rows

Dim i As Integer
Dim target As DataTable = dt.Clone()
For i = 0 To PageSize - 1
Dim index As Integer = i + firstIndexInPage
If index < rows.Count Then
target.ImportRow(rows(i + firstIndexInPage))
Else
Exit For
End If
Next

Return target
End Function
End Class
 
S

Steven Cheng[MSFT]

Hi Richard,


Thanks for posting in the community!
From your description, checkbox in it. The Repeater retrieve data from
database and stored in session for further
use, also the user implemented paging himself. However, he want the each
page's state(for the
checkbox ) be stored for further use if page is changed.
If there is anything I misunderstood, please feel free to let me know.

I've read the page's code you provided, it's very helpful. Now, I've
completely got your requirment. In the page, you loaded the Data From
database the first time the page is loaded and store the DataTable into the
Session so as for further use. Your code is as below:
Public Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not (IsPostBack) Then
LoadData()
End If

Dim data As DataTable = Session("SearchResults")
Repeater1.DataSource = data
Repeater1.DataBind()

End Sub
However, I don't think the
Dim data As DataTable = Session("SearchResults")
Repeater1.DataSource = data
Repeater1.DataBind()
is needed since you only need to rebind repeater control when first loaded
or page index changed, yes? Please have a check on this to see if I've
misunderstanded your purpose.

And as for the paging, your implement is everytime when page changed(user
click next or prevous button). You'll modify the currentpageindex and then
use "GetPage" function to retrieve the proper page's data from the
DataTable in the session(use clone to create a new DataTAble and imports
the rows in terms of the page index). After that , rebind the repeater
control with the new Data. So the problem is that you haven't done any
operations to stored the old page's states when page changed , that' why
you'll lose the checkboxs' states. My suggestion is that when user click a
certain button to fire the paging event, you first loop through the
repeater and then get all the checkboxes's current state and update their
related value in the DataTable which is stored in the Session. Thus, the
next time, user page back to this page, the certain page's data retrieved
from the Session will be remain the states in of last time. For example, as
for your original code, you use the below code when paging :
Public Sub OnPreviousPage(ByVal sender As Object, ByVal e As EventArgs)
CurrentPageIndex -= 1
RefreshPage()
End Sub

Public Sub OnNextPage(ByVal sender As Object, ByVal e As EventArgs)
CurrentPageIndex += 1
RefreshPage()
End Sub

Now Add a certain function to store the current page's state
values(checkbox's value). Such as
Public Sub OnPreviousPage(ByVal sender As Object, ByVal e As EventArgs)
StoreOldPage()
CurrentPageIndex -= 1
RefreshPage()
End Sub

Public Sub OnNextPage(ByVal sender As Object, ByVal e As EventArgs)
StoreOldPage()
CurrentPageIndex += 1
RefreshPage()
End Sub

In the StoreOldPage(), you just retrieve the DataTable from session and
update the table's certain datarows' certain column's value(related to the
checkbox's column). How do you think of this?
BTW, since I've mentioned before that the using session state will somewhat
reduce the application's performance. I think you'd consider whether it
really necessary to implement it this way.

Please check out the above suggestion. If you have any questions, please
feel free to post here.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Steven Cheng[MSFT]

Hi Mark,


Have you had a chance to check out my previous suggestions or have you got
any ideas on this issue? Please feel free to let me know if you need any
further assistance.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top