Rainbow是C#编写的一个优秀的开源门户网站项目。无论是实际应用还是拿来学习,都是一个不错的选择。目前似乎汉化最好的是RC4的版本,在bussoft有下载。但遗憾的是其中很多的功能模块都不提供分页的功能。在网上找了下,发现以下的解决方案:
Rainbow其实已经自带分页的功能支持,如在Rainbow.UI.WebControls下,IPaging接口、Paging和PagingNumbers控件在RC4版本中都是现成的了。
在每个对应模块中按照一定的步骤适当修改一下原有的代码及其存储过程,就可以达到分页的目的:
以Announcements模块为例:
1. 增加代码到ascx的头部分:
<%
@ Register TagPrefix
=
"
cc2
"
Namespace
=
"
Rainbow.UI.WebControls
"
Assembly
=
"
Rainbow
"
%>
在需要放置分页器的地方放置以下代码:
<
p align
=
right
><
cc2:Paging id
=
"
pgModules
"
runat
=
"
server
"
/></
p
>
这个是放置在右下角的例子。
2. 在ascx对应的cs代码中声明分页器模块:
protected
Rainbow.UI.WebControls.IPaging pgModules;
3. 声明分页的缺省大小:
SettingItem PageSize
=
new
SettingItem(
new

Rainbow.UI.DataTypes.IntegerDataType());
PageSize.Value
=
"
10
"
;
this
._baseSettings.Add(
"
PageSize
"
,PageSize);
放在构造函数Announcement()中。
4. 在初始化OnInit代码部分添加事件代理的响应:
pgModules.OnMove
+=
new
EventHandler(Page_Changed);
5. 当然需要添加对应的Page_Changed代码:
private
void
Page_Changed(
object
sender, System.EventArgs e)

{
pgModules.RecordsPerPage = Int32.Parse(Settings["PageSize"].ToString());
BindList(pgModules.PageNumber);
}
6. 定义新的DataBind函数:
private
void
BindList(
int
Page)

{
string sortField = Settings["SortField"].ToString();
string sortDirection = Settings["SortDirection"].ToString();

AnnouncementsDB announcements = new AnnouncementsDB();
DataSet announces = announcements.GetAnnouncementsPaged(ModuleID,

Version,Page,pgModules.RecordsPerPage);
if (announces.Tables.Count>0 && announces.Tables[0].Rows.Count >0)

{
pgModules.RecordCount = (int)(announces.Tables[0].Rows[0]["RecordCount"]);
}

DataView myDataView = new DataView();
myDataView = announces.Tables[0].DefaultView;
myDataView.Sort = sortField + " " + sortDirection;
myDataList.DataSource = myDataView;
myDataList.DataBind();
}
7. 在Page_Load中,替换掉原来的Databind的方法:
pgModules.RecordsPerPage
=
Int32.Parse(Settings[
"
PageSize
"
].ToString());
BindList(pgModules.PageNumber);
8. 在数据库中建立对应的分页操作的存储过程,如 rb_GetAnnouncementsPaged,注意付给适当的权限。
CREATE
PROCEDURE
rb_GetAnnouncementsPaged
(
@ModuleID
int
,
@WorkflowVersion
int
,
@Page
int
,
@RecordsPerPage
int
)
AS

DECLARE
@FirstRec
int
, @LastRec
int

CREATE
TABLE
#TempItems
(
ID
int
IDENTITY
,
ItemID
int
,
CreatedByUser
nvarchar
(
100
),
CreatedDate
datetime
,
Title
nvarchar
(
150
),
MoreLink
nvarchar
(
150
),
MobileMoreLink
nvarchar
(
150
),
ExpireDate
datetime
,
Description
nvarchar
(
2000
)
)

BEGIN
SET
NOCOUNT
ON

IF
( @WorkflowVersion
=
1
)
INSERT
INTO
#TempItems
(
ItemID, CreatedByUser, CreatedDate, Title,
MoreLink, MobileMoreLink, ExpireDate, Description
)
SELECT
ItemID,
CreatedByUser,
CreatedDate,
Title,
MoreLink,
MobileMoreLink,
ExpireDate,
Description
FROM
rb_Announcements
WHERE
ModuleID
=
@ModuleID
AND
ExpireDate
>
GETDATE
()
ORDER
BY
CreatedDate
DESC
ELSE
INSERT
INTO
#TempItems
(
ItemID, CreatedByUser, CreatedDate, Title,
MoreLink, MobileMoreLink, ExpireDate, Description
)
SELECT
ItemID,
CreatedByUser,
CreatedDate,
Title,
MoreLink,
MobileMoreLink,
ExpireDate,
Description
FROM
rb_Announcements_st
WHERE
ModuleID
=
@ModuleID
AND
ExpireDate
>
GETDATE
()
ORDER
BY
CreatedDate
DESC

SELECT
@FirstRec
=
(@Page
-
1
)
*
@RecordsPerPage
SELECT
@LastRec
=
(@Page
*
@RecordsPerPage
+
1
)

SELECT
*
, (
SELECT
COUNT
(
*
)
FROM
#TempItems) RecordCount
FROM
#TempItems
WHERE
ID
>
@FirstRec
AND
ID
<
@LastRec

SET
NOCOUNT
OFF
END

GO
9. 当然,数据访问层也需要修改,如6中也可以看到了,需要增加GetAnnouncementsPaged函数在AnnouncementsDB中:
public
DataSet GetAnnouncementsPaged(
int
moduleID, WorkFlowVersion version,
int
page,

int
perPageNumber)

{
SqlConnection myConnection = PortalSettings.SqlConnectionString;
SqlDataAdapter myCommand = new SqlDataAdapter("rb_GetAnnouncementsPaged", myConnection);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parameterModuleID = new SqlParameter("@ModuleID", SqlDbType.Int, 4);
parameterModuleID.Value = moduleID;
myCommand.SelectCommand.Parameters.Add(parameterModuleID);
SqlParameter parameterWorkflowVersion = new SqlParameter("@WorkflowVersion", SqlDbType.Int, 4);
parameterWorkflowVersion.Value = (int)version;
myCommand.SelectCommand.Parameters.Add(parameterWorkflowVersion);
SqlParameter parameterPage = new SqlParameter("@Page", SqlDbType.Int, 4);
parameterPage.Value = page;
myCommand.SelectCommand.Parameters.Add(parameterPage);
SqlParameter parameterPerPageNumber = new SqlParameter("@RecordsPerPage", SqlDbType.Int, 4);
parameterPerPageNumber.Value = perPageNumber;
myCommand.SelectCommand.Parameters.Add(parameterPerPageNumber);
DataSet myDataSet = new DataSet();
try

{
myCommand.Fill(myDataSet);
}
finally

{
myConnection.Close();
10. 有些模块原来是使用SqlDataReader的,在分页中也可以适当将其分页用DataSet来替代,如Discussion模块。
附件是几个模块分页的存储过程。