第一步的目的就是先写一个简单的首页,里面只有一个论坛分组的列表,论坛以CSDN的为例,取了前三个大分类模拟记录。1.建表我喜欢用Ecxel写文档数据库说明,比较方便,还有很多偷懒的技巧。表名是bbs_board
结构如下:
1 BoardID int 自增 主键
2 BoardName nvarchar 100 论坛分组名称
3 BoardLevel int 论坛分组类型。1:大分类;2:小分类
4 ParentID int 0 父ID。上级节点的ID
5 ChildCount int 0 子栏目数量
6 OrderID int 0 排序用
7 TopicNum int 0 主题数
8 PostNum int 0 回复数
9 todayNum int 0 今日主题数
10 AddedDate datetime getDate() 添加时间
11 BoardMasterID nvarchar 200 版主ID(会员ID)
12 BoardMaster nvarchar 1000 版主
13 Readme nvarchar 1000 论坛分组的介绍
14 LastPost nvarchar 1000 最后发帖情况 分组采用无级分组的设计,但是实际上只有两极——大分类和小分类。2.填入模拟数据我用了CSDN的几个分类作为模拟记录3.编写.asp.cs文件既然是二级分组,那么就涉及到了控件嵌套的问题,最简便的方法呢就是外面用DataList,里面用DataGrid。
灵活的方法呢就是用Repeater套Repeater,这样呢既节省了资源,又能够满足各种复杂页面的要求。下面先说一下简便的方法:A.利用数据层取得记录集
Jyk.DAL add = new Jyk.DAL();
DataView dv = add.runSqlDataSet("select * from bbs_board").Tables[0].DefaultView;
这里建立了一个DataView 对象来存储记录。B.绑定DataList
dv.RowFilter = "ParentID = 0";
DL1.DataSource=dv;
DL1.DataBind();利用RowFilter属性来取得大分类的记录
下面就是绑定代码了add.Dispose();C.绑定DataList里面的DataGrid
DataGrid tmpDG = new DataGrid();
foreach (DataListItem item in DL1.Items )
{
dv.RowFilter = "ParentID = " + DL1.DataKeys[item.ItemIndex].ToString();
tmpDG = (DataGrid)item.FindControl("DG");
tmpDG.DataSource=dv;
tmpDG.DataBind();
}
常见的思路呢是在DataList的ItemDataBound事件里面绑定,我觉得那么写效率不好,所以我采用遍历的方法来实现。
先定义一个临时的DataGrid对象,用来存放DataList里面的DataGrid,然后遍历DataList,取得每一行的DataGrid,最后就是绑定。
当然了要先设置DL1 的 DataKeys 属性(DL1.DataKeys="BoardID";),用它来存放大分类的ID,然后在遍历里面用
DL1.DataKeys[item.ItemIndex].ToString();
来取出大分类的ID,用于去度对应的小分类。D.释放资源
add.Dispose();最后释放资源。
Repeater的方法基本上是一样的,换一下对象名就行了。我就不详细说明了Jyk.DAL add = new Jyk.DAL();
DataView dv = add.runSqlDataSet("select * from bbs_board").Tables[0].DefaultView;dv.RowFilter = "ParentID = 0";
Rpt1.DataSource=dv;
Rpt1.DataBind();
Repeater tmpRpt = new Repeater();
foreach (RepeaterItem item in Rpt1.Items )
{
tmpRpt = (Repeater)item.FindControl("Rpt2");
dv.RowFilter = "ParentID = " + tmpRpt.DataMember ;
tmpRpt.DataSource=dv;
tmpRpt.DataBind();
}
add.Dispose();对了,有一点要说明一下。Repeater没有DataKeys属性,但是我们可以用DataMember来代替。这个是写在里层的Repeater的。还有一个要说明的,如果按照三层结构的思路呢,应该建立一个.cs文件,然后把取得记录集的两行语句放进去。
我觉得这么写很是麻烦,分出去写还是两行代码没有减少,而且还要多一个.cs文件,等等,好像三层结构是不可以返回一个杂乱无章的记录集的,要分开写,返回大分类的记录集绑定外边的控件;再返回第一个大分类的小分类的记录集来绑定里面的第一个控件,然后是第二个,第三个......
我对三层结构理解的不深,不知道是不是这个意思。
4.描绘.aspx页面这个是很重要的了,给人的第一感觉是由页面来决定的,这就要烦劳美工来帮忙了,我是不行的,我只会把美工写好的html代码拿来用现成的。现在呢没人帮忙,只好写“素面”了,就是没有美化的页面。A.DataList——DataGrid法
<asp:datalist id="DL1" runat="server" DataKeyField="BoardID">
<ItemTemplate>
<asp:Label id=Lbl_title runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.BoardName") %>'></asp:Label>
<br>
<asp:datagrid id="DG" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="BoardName" HeaderText="讨论区"></asp:BoundColumn>
<asp:BoundColumn DataField="TopicNum" HeaderText="主题数"></asp:BoundColumn>
<asp:BoundColumn DataField="PostNum" HeaderText="帖子数"></asp:BoundColumn>
<asp:BoundColumn DataField="LastPost" HeaderText="最后发表"></asp:BoundColumn>
<asp:BoundColumn DataField="BoardMaster" HeaderText="版主"></asp:BoundColumn>
</Columns>
</asp:datagrid>
</ItemTemplate>
</asp:datalist>
B.Repeater——Repeater法
<asp:Repeater id="Rpt1" runat="server">
<HeaderTemplate>
<table border="0" width="500" cellspacing="0" rules="all">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td colspan="5">
<%# DataBinder.Eval(Container, "DataItem.BoardName") %>
</td>
</tr>
<!--放里面的Repeater。为了能清楚一点,写在了下面。用的时候要把下面的代码考进来。-->
</ItemTemplate>
<FooterTemplate>
</TABLE>
</FooterTemplate>
</asp:Repeater>//里面的Repeater
<asp:Repeater id="Rpt2" runat="server" DataMember='<%# DataBinder.Eval(Container, "DataItem.BoardID") %>'>
<HeaderTemplate>
<tr>
<td>讨论区</td>
<td>主题数</td>
<td>帖子数</td>
<td>最后发表</td>
<td>版主</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container, "DataItem.BoardName") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.TopicNum") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.PostNum") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.LastPost") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.BoardMaster") %>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
<asp:Repeater id="Rpt2" runat="server" DataMember='<%# DataBinder.Eval(Container, "DataItem.BoardID") %>'>
这是里面的Repeater,注意 DataMember 的写法。
结构如下:
1 BoardID int 自增 主键
2 BoardName nvarchar 100 论坛分组名称
3 BoardLevel int 论坛分组类型。1:大分类;2:小分类
4 ParentID int 0 父ID。上级节点的ID
5 ChildCount int 0 子栏目数量
6 OrderID int 0 排序用
7 TopicNum int 0 主题数
8 PostNum int 0 回复数
9 todayNum int 0 今日主题数
10 AddedDate datetime getDate() 添加时间
11 BoardMasterID nvarchar 200 版主ID(会员ID)
12 BoardMaster nvarchar 1000 版主
13 Readme nvarchar 1000 论坛分组的介绍
14 LastPost nvarchar 1000 最后发帖情况 分组采用无级分组的设计,但是实际上只有两极——大分类和小分类。2.填入模拟数据我用了CSDN的几个分类作为模拟记录3.编写.asp.cs文件既然是二级分组,那么就涉及到了控件嵌套的问题,最简便的方法呢就是外面用DataList,里面用DataGrid。
灵活的方法呢就是用Repeater套Repeater,这样呢既节省了资源,又能够满足各种复杂页面的要求。下面先说一下简便的方法:A.利用数据层取得记录集
Jyk.DAL add = new Jyk.DAL();
DataView dv = add.runSqlDataSet("select * from bbs_board").Tables[0].DefaultView;
这里建立了一个DataView 对象来存储记录。B.绑定DataList
dv.RowFilter = "ParentID = 0";
DL1.DataSource=dv;
DL1.DataBind();利用RowFilter属性来取得大分类的记录
下面就是绑定代码了add.Dispose();C.绑定DataList里面的DataGrid
DataGrid tmpDG = new DataGrid();
foreach (DataListItem item in DL1.Items )
{
dv.RowFilter = "ParentID = " + DL1.DataKeys[item.ItemIndex].ToString();
tmpDG = (DataGrid)item.FindControl("DG");
tmpDG.DataSource=dv;
tmpDG.DataBind();
}
常见的思路呢是在DataList的ItemDataBound事件里面绑定,我觉得那么写效率不好,所以我采用遍历的方法来实现。
先定义一个临时的DataGrid对象,用来存放DataList里面的DataGrid,然后遍历DataList,取得每一行的DataGrid,最后就是绑定。
当然了要先设置DL1 的 DataKeys 属性(DL1.DataKeys="BoardID";),用它来存放大分类的ID,然后在遍历里面用
DL1.DataKeys[item.ItemIndex].ToString();
来取出大分类的ID,用于去度对应的小分类。D.释放资源
add.Dispose();最后释放资源。
Repeater的方法基本上是一样的,换一下对象名就行了。我就不详细说明了Jyk.DAL add = new Jyk.DAL();
DataView dv = add.runSqlDataSet("select * from bbs_board").Tables[0].DefaultView;dv.RowFilter = "ParentID = 0";
Rpt1.DataSource=dv;
Rpt1.DataBind();
Repeater tmpRpt = new Repeater();
foreach (RepeaterItem item in Rpt1.Items )
{
tmpRpt = (Repeater)item.FindControl("Rpt2");
dv.RowFilter = "ParentID = " + tmpRpt.DataMember ;
tmpRpt.DataSource=dv;
tmpRpt.DataBind();
}
add.Dispose();对了,有一点要说明一下。Repeater没有DataKeys属性,但是我们可以用DataMember来代替。这个是写在里层的Repeater的。还有一个要说明的,如果按照三层结构的思路呢,应该建立一个.cs文件,然后把取得记录集的两行语句放进去。
我觉得这么写很是麻烦,分出去写还是两行代码没有减少,而且还要多一个.cs文件,等等,好像三层结构是不可以返回一个杂乱无章的记录集的,要分开写,返回大分类的记录集绑定外边的控件;再返回第一个大分类的小分类的记录集来绑定里面的第一个控件,然后是第二个,第三个......
我对三层结构理解的不深,不知道是不是这个意思。
4.描绘.aspx页面这个是很重要的了,给人的第一感觉是由页面来决定的,这就要烦劳美工来帮忙了,我是不行的,我只会把美工写好的html代码拿来用现成的。现在呢没人帮忙,只好写“素面”了,就是没有美化的页面。A.DataList——DataGrid法
<asp:datalist id="DL1" runat="server" DataKeyField="BoardID">
<ItemTemplate>
<asp:Label id=Lbl_title runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.BoardName") %>'></asp:Label>
<br>
<asp:datagrid id="DG" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundColumn DataField="BoardName" HeaderText="讨论区"></asp:BoundColumn>
<asp:BoundColumn DataField="TopicNum" HeaderText="主题数"></asp:BoundColumn>
<asp:BoundColumn DataField="PostNum" HeaderText="帖子数"></asp:BoundColumn>
<asp:BoundColumn DataField="LastPost" HeaderText="最后发表"></asp:BoundColumn>
<asp:BoundColumn DataField="BoardMaster" HeaderText="版主"></asp:BoundColumn>
</Columns>
</asp:datagrid>
</ItemTemplate>
</asp:datalist>
B.Repeater——Repeater法
<asp:Repeater id="Rpt1" runat="server">
<HeaderTemplate>
<table border="0" width="500" cellspacing="0" rules="all">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td colspan="5">
<%# DataBinder.Eval(Container, "DataItem.BoardName") %>
</td>
</tr>
<!--放里面的Repeater。为了能清楚一点,写在了下面。用的时候要把下面的代码考进来。-->
</ItemTemplate>
<FooterTemplate>
</TABLE>
</FooterTemplate>
</asp:Repeater>//里面的Repeater
<asp:Repeater id="Rpt2" runat="server" DataMember='<%# DataBinder.Eval(Container, "DataItem.BoardID") %>'>
<HeaderTemplate>
<tr>
<td>讨论区</td>
<td>主题数</td>
<td>帖子数</td>
<td>最后发表</td>
<td>版主</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container, "DataItem.BoardName") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.TopicNum") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.PostNum") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.LastPost") %>
</td>
<td><%# DataBinder.Eval(Container, "DataItem.BoardMaster") %>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
<asp:Repeater id="Rpt2" runat="server" DataMember='<%# DataBinder.Eval(Container, "DataItem.BoardID") %>'>
这是里面的Repeater,注意 DataMember 的写法。
解决方案 »
- 在循环遍历的时候 报System.ArgumentException: 已存在具有相同键的条目是什么问题?
- 我想做一个全选功能,代码写完了,但是不起做用。大家帮忙看看
- 高手请教GridView1的翻页问题
- 寻求最佳方法!(关于对某一行记录的操作)
- 有没有.net技术实现的BT服务器和客户端?有开源的么?
- 新手,代码总是报这个错,帮我看一下!
- ASP.NET下载问题!
- 如何得到一服务器控件的所有事件列表?
- 如何使我的DataGrid控件的行间距不会自动变化!谢谢!!
- 求解:JavaScript 里面的函数在触发事件,保存数据结束之后再执行!谢谢!!
- 为什么我已经用了ClOB的数据类型了,怎么插入字符串的时候,还报字符过长的错误?长度只有4万不到
- 请问如何设置formatstring来缩略显示字符串?
这是演示页面,没有美化,所以呢很是难看了,建议看之前先做好心理准备:)
一般上论坛的人都是问问题的都比较匆忙,没有时间看
<asp:repeater runat="server" > //主Repeater
<ItemTemplte>
<table><tr><td>主题号<a><%# DataBinder.Eval(Container, "DataItem.TopicID") %></a></td>
<td>主题名:<a><%# DataBinder.Eval(Container, "DataItem.TopicName") %></a></td>
<td>最后回复时间:<a><%# DataBinder.Eval(Container, "DataItem.LastPost") %></a></td>
..........
.........
</tr></table>
<asp:repeater runat DataSoure='<% GetAllApplyAboutThisTopic(DataBinder.Eval (Container, "DataItem.TopicID") )%>'> //GetAllApplayAboutThisTipic为后台代码中一函数, //返回一数据绑定源,如dataset,datatable,dataview
//其中传了一参数(TopicID:主题号)以得到关于某一 //主题的所有回复。。<itemItemplate>
关于此主题的回复:
回复号:<%# DataBinder.Eval(Container, "DataItem.ReplyID") %><br>
回复人:<%# DataBinder.Eval(Container, "DataItem.ReplyUser") %><br>
回复内容:<%# DataBinder.Eval(Container, "DataItem.ReplyContent") %><br>
</ItemTemplate</itemItemplate>
</repeater>
类似于这样。可以在repeater 中嵌套repeater(可以形成多重嵌套,如3层repeater,4层repeater嵌套)
我在这样提出。最好用repeater,因为repeater数据绑定在页面层带来的开销是最小的。(比datalisgt,datagrid都要小)
这是数据层
DataView dv = add.runSqlDataSet("select * from bbs_board").Tables[0].DefaultView;
这是数据层的一个方法,传入查询语句,返回DataSet.