In addition to the GridViews control with the threads, the page also features a DropDownList at the top of the page, which lists all available forums(retrieved by an ObjectDataSource that uses the Forum.GetForums business method) and allow user quickly navigate to a forum by selecting one. The DropDownList OnChange client-side (javaScript)event redirects to the user to the same BrowseThread.aspx page, with the newly selected forun's ID on the query string:
<
asp:Content ID="MainContent" ContentPlaceHolderID="MainContent" Runat="Server">
<div class="sectiontitle">
<asp:Literal runat="server" ID="lblPageTitle" Text="Threads from forum: " />
<asp:DropDownList ID="ddlForums" runat="server" DataSourceID="objForums" DataTextField="Title" DataValueField="ID"
onchange="javascript:">
</asp:DropDownList><asp:ObjectDataSource ID="objForums" runat="server" SelectMethod="GetForums"
TypeName="MB.maatechources.BLL.Forums.Forum"></asp:ObjectDataSource>
</div>
<p></p>
<div style="text-align: center;font-weight: bold"><asp:HyperLink runat="server" ID="lnkNewThread1" NavigateUrl="AddEditPost.aspx?ForumID={0}">Create new thread</asp:HyperLink></div>
<p></p>
<asp:GridView ID="gvwThreads" runat="server" AllowPaging="True" AutoGenerateColumns="False"
DataSourceID="objThreads" PageSize="25" AllowSorting="True" DataKeyNames="ID" OnRowCommand="gvwThreads_RowCommand" OnRowCreated="gvwThreads_RowCreated">
<Columns>
<asp:TemplateField ItemStyle-Width="16px">
<ItemTemplate>
<asp:Image runat="server" ID="imgThread" ImageUrl="~/Images/Thread.gif" Visible='<%# (int)Eval("ReplyCount") < Globals.Settings.Forums.HotThreadPosts %>' GenerateEmptyAlternateText="true" />
<asp:Image runat="server" ID="imgHotThread" ImageUrl="~/Images/ThreadHot.gif" Visible='<%# (int)Eval("ReplyCount") >= Globals.Settings.Forums.HotThreadPosts %>' GenerateEmptyAlternateText="true" />
</ItemTemplate>
<HeaderStyle HorizontalAlign="Left" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Title">
<ItemTemplate>
<asp:HyperLink ID="lnkTitle" runat="server" Text='<%# Eval("Title") %>'
NavigateUrl='<%# "ShowThread.aspx?ID=" + Eval("ID") %>' /><br />
<small>by <asp:Label ID="lblAddedBy" runat="server" Text='<%# Eval("AddedBy") %>'></asp:Label></small>
</ItemTemplate>
<HeaderStyle HorizontalAlign="Left" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Last Post" SortExpression="LastPostDate">
<ItemTemplate>
<small><asp:Label ID="lblLastPostDate" runat="server" Text='<%# Eval("LastPostDate", "{0:g}") %>'></asp:Label><br />
by
<asp:Label ID="lblLastPostBy" runat="server" Text='<%# Eval("LastPostBy") %>'></asp:Label></small>
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" Width="130px" />
<HeaderStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:BoundField HeaderText="Replies" DataField="ReplyCount" SortExpression="ReplyCount" >
<ItemStyle HorizontalAlign="Center" Width="50px" />
<HeaderStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:BoundField HeaderText="Views" DataField="ViewCount" SortExpression="ViewCount" >
<ItemStyle HorizontalAlign="Center" Width="50px" />
<HeaderStyle HorizontalAlign="Center" />
</asp:BoundField>
<asp:HyperLinkField Text="<img border='0' src='Images/MoveThread.gif' alt='Move thread' />"
DataNavigateUrlFormatString="~/Admin/MoveThread.aspx?ThreadID={0}" DataNavigateUrlFields="ID">
<ItemStyle HorizontalAlign="Center" Width="20px" />
</asp:HyperLinkField>
<asp:ButtonField ButtonType="Image" ImageUrl="~/Images/LockSmall.gif" CommandName="Close" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="20px" />
<asp:CommandField ButtonType="Image" DeleteImageUrl="~/Images/Delete.gif" DeleteText="Delete thread" ShowDeleteButton="True">
<ItemStyle HorizontalAlign="Center" Width="20px" />
</asp:CommandField>
</Columns>
<EmptyDataTemplate><b>No threads to show</b></EmptyDataTemplate>
</asp:GridView>
<p></p>
<div style="text-align: center;font-weight: bold"><asp:HyperLink runat="server" ID="lnkNewThread2" NavigateUrl="AddEditPost.aspx?ForumID={0}">Create new thread</asp:HyperLink></div>
The GridView bound to another Object DataSource control, which specifies the methods to select and delete data. Because we want to support Pagination, we use the GetThreadCount method to return the total thread count. To sipport sorting you must get SortParameterName to the name of the parameter that the SELECtMethod(ie., GetThreads) will use to receive the sort expression; in this case, as show earlier, it's sortExpression. Here is the example code:
<asp:ObjectDataSource ID="objThreads" runat="server" DeleteMethod="DeletePost" SelectMethod="GetThreads" SelectCountMethod="GetThreadCount"
TypeName="MB.maatechources.BLL.Forums.Post" EnablePaging="true" SortParameterName="sortExpression">
<DeleteParameters>
<asp:Parameter Name="id" Type="Int32" />
</DeleteParameters>
<SelectParameters>
<asp:QueryStringParameter Name="forumID" QueryStringField="ForumID" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
</
asp:Content>
BrowseThread.aspx.cs
namespace
MB.maatechsources.UI
{
public partial class BrowseThreads : BasePage
{
protected void Page_Init(object sender, EventArgs e)
{
gvwThreads.PageSize =
Globals.Settings.Forums.ThreadsPageSize;
}
protected void Page_Load(object sender, EventArgs e)
{
this.Master.EnablePersonalization = true;
if (!this.IsPostBack)
{
string forumID = this.Request.QueryString["ForumID"];
lnkNewThread1.NavigateUrl =
string.Format(lnkNewThread1.NavigateUrl, forumID);
lnkNewThread2.NavigateUrl = lnkNewThread1.NavigateUrl;
Forum forum = Forum.GetForumByID(int.Parse(forumID));
this.Title = string.Format(this.Title, forum.Title);
ddlForums.SelectedValue = forumID;
// if the user is not an admin, editor or moderator, hide the grid's column with
// the commands to delete, close or move a thread
bool canEdit = (this.User.Identity.IsAuthenticated &&
(
this.User.IsInRole("Administrators") || this.User.IsInRole("Editors") || this.User.IsInRole("Moderators")));
gvwThreads.Columns[5].Visible = canEdit;
gvwThreads.Columns[6].Visible = canEdit;
gvwThreads.Columns[7].Visible = canEdit;
}
}
protected void gvwThreads_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
ImageButton btnClose = e.Row.Cells[6].Controls[0] as ImageButton;
btnClose.OnClientClick =
"if (confirm('Are you sure you want to close this thread?') == false) return false;";
btnClose.ToolTip =
"Close this thread";
ImageButton btnDelete = e.Row.Cells[7].Controls[0] as ImageButton;
btnDelete.OnClientClick =
"if (confirm('Are you sure you want to delete this thread?') == false) return false;";
}
}
protected void gvwThreads_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Close")
{
int threadPostID = Convert.ToInt32(
gvwThreads.DataKeys[
Convert.ToInt32(e.CommandArgument)][0]);
MB.matechsources.BLL.Forums.
Post.CloseThread(threadPostID);
}
}
}
}
Continue in the next example of Forum of maatechources BrowserThread.aspx, ...