📄 postthreaded.cs
字号:
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AspNetForums;
using AspNetForums.Components;
using System.ComponentModel;
namespace AspNetForums.Controls {
/// <summary>
/// This Web control displays a thread in a threaded display. The developer may pass in
/// either a PostID or a ThreadID. If a PostID is passed in, the thread that that Post belongs
/// to is constructed.
/// </summary>
[
ParseChildren(true)
]
public class PostThreaded : WebControl, INamingContainer {
// Class constants
const String defaultPostDateTimeFormat = "ddd MMM dd, yyyy hh:mm tt";
// Member variable used to display threads
Repeater threadedRepeater;
ITemplate threadItemTemplate;
ITemplate threadBelowThreshHoldItemTemplate;
ITemplate bodyTemplate;
// Member variables used to keep track of where we are in the thread
int threadedStartPostLevel = 1;
int threshHold = 1;
User postUser;
// *********************************************************************
// ThreadView
//
/// <summary>
/// Class constructor. We'll attempt to get the PostID or ThreadID
/// </summary>
///
// ********************************************************************/
public PostThreaded() {
// If we have an instance of context, let's attempt to
// get the PostID so we can save the user from writing
// the code
try {
if (null != Context.Request.QueryString["PostID"]) {
string postID = Context.Request.QueryString["PostID"];
// Contains a #
if (postID.IndexOf("#") > 0)
postID = postID.Substring(0, postID.IndexOf("#"));
this.PostID = Convert.ToInt32(postID);
} else if (null != Context.Request.Form["PostId"]) {
this.PostID = Convert.ToInt32(Context.Request.Form["PostID"]);
}
} catch (Exception e) {
HttpContext.Current.Response.Redirect(Globals.UrlMessage + Convert.ToInt32(Messages.PostDoesNotExist));
HttpContext.Current.Response.End();
}
}
// *********************************************************************
// BuildItemTemplate
//
/// <summary>
/// Used to create the ItemTemplate value if a template is not provided.
/// </summary>
///
// ********************************************************************/
private void BuildItemTemplate(Control _ctrl) {
System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(_ctrl));
__parser.AddParsedSubObject(RenderItemTemplate());
}
// *********************************************************************
// RenderItemTemplate
//
/// <summary>
/// Creates, DataBinds, and returns a table Control. This table control
/// is where the body of the thread is injected. We DataBind the table since
/// multiple rows may be added depending on the format chosen.
/// </summary>
///
// ********************************************************************/
private Control RenderItemTemplate() {
Table table = new Table();
table.CellPadding = 2;
table.CellSpacing = 0;
table.Width = Unit.Percentage(100);
table.DataBinding += new System.EventHandler(DataBindThread);
return table;
}
// *********************************************************************
// DataBindThread
//
/// <summary>
/// Performs the DataBinding for each thread item bound to the repeater.
/// </summary>
///
// ********************************************************************/
private void DataBindThread(Object sender, EventArgs e) {
Table table;
TableRow tr;
TableCell td;
RepeaterItem container;
Post post;
bool isBelowThreshHold = false;
bool isFirstPost = false;
// Get the table instance we databound
table = (Table) sender;
// Get the data item to be bound to
container = (RepeaterItem) table.NamingContainer;
// Extract the original databound class type
post = (Post) container.DataItem;
// If we're the first item, set the threadedStartPostLevel.
// This private member variable determines what nesting level
// to start at.
if (container.ItemIndex == 0) {
threadedStartPostLevel = post.PostLevel;
isFirstPost = true;
}
// Determine if we are below the threshold of threads to display
// with body.
if ((post.PostLevel - threadedStartPostLevel) > Threshhold)
isBelowThreshHold = true;
// This whitespace is used to separate thread items
if ((!isBelowThreshHold) && (!isFirstPost)) {
// Add some white space
tr = new TableRow();
td = new TableCell();
td.ColumnSpan = 2;
td.Height = Unit.Pixel(12);
tr.Controls.Add(td);
table.Controls.Add(tr);
}
// Prepare to display the thread
tr = new TableRow();
// If we're not the first post, indent
if (!isFirstPost) {
// Indenting
td = new TableCell();
td.Wrap = false;
td.VerticalAlign = VerticalAlign.Top;
Label indent = new Label();
indent.CssClass = "normalTextSmallBold";
indent.DataBinding += new System.EventHandler(HandleIndentingForThreaded);
td.Controls.Add(indent);
tr.Controls.Add(td);
}
// Databind this cell for the actual thread display
td = new TableCell();
td.DataBinding += new System.EventHandler(HandleDataBindingForThreadTitle);
if (isFirstPost) {
td.ColumnSpan = 2;
} else {
td.Width = Unit.Percentage(100);
}
tr.Controls.Add(td);
table.Controls.Add(tr);
// Display body of post
if (!isBelowThreshHold) {
td = new TableCell();
tr = new TableRow();
// Set some properties on the row
td.CssClass = "forumRow";
// If we're not the first item, let's add a bit of whitespace
if (isFirstPost) {
td.ColumnSpan = 2;
} else {
tr.Controls.Add(new TableCell());
}
// Template?
if (null != this.BodyTemplate) {
BodyTemplate.InstantiateIn(td);
tr.Controls.Add(td);
table.Controls.Add(tr);
return;
}
Label body = new Label();
// Set up the body text
body.CssClass = "normalTextSmall";
body.Text = Globals.FormatPostBody(post.Body);
postUser = Users.GetUserInfo(post.Username, false);
if (postUser.Signature != "") {
body.Text += Globals.FormatSignature(postUser.Signature);
}
// Add the body to the cell
td.Controls.Add(body);
tr.Controls.Add(td);
table.Controls.Add(tr);
}
}
// *********************************************************************
// HandleDataBindingForThreadDisplay
//
/// <summary>
/// Perform databinding and control the display of a given thread.
/// </summary>
///
// ********************************************************************/
private void HandleDataBindingForThreadTitle (Object sender, EventArgs e) {
TableCell td;
RepeaterItem container;
Post post;
bool isBelowThreshHold = false;
// Bound to type TableCell
td = (TableCell) sender;
// Get the repeater item containing the bound data
container = (RepeaterItem) td.NamingContainer;
// Get the original class type we're bound to
post = (Post) container.DataItem;
// Determine if we are below the threshold of threads to display
// with body.
if ((post.PostLevel - threadedStartPostLevel) > Threshhold)
isBelowThreshHold = true;
// Format differently based on the threshold to view nested posts
if (isBelowThreshHold) {
// Do we have a template
if (this.ThreadBelowThreshHoldItemTemplate != null){
ThreadBelowThreshHoldItemTemplate.InstantiateIn(td);
return;
}
// Label for display
Label label = new Label();
// Add bullet
LiteralControl bullet = new LiteralControl();
bullet.Text = "<img src=\"" + Globals.ApplicationVRoot + "/skins/" + Globals.Skin + "/images/node.gif" + "\">";
label.Controls.Add(bullet);
// Subject
HyperLink subject = new HyperLink();
subject.Text = post.Subject;
subject.CssClass = "linkSmallBold";
subject.NavigateUrl = Globals.UrlShowPost + post.PostID + "&View=Threaded&ThreshHold=" + (Convert.ToInt32(post.PostLevel) + 1) + "#" + post.PostID;
label.Controls.Add(subject);
// Whitespace
label.Controls.Add(new LiteralControl(" "));
// Author
HyperLink author = new HyperLink();
author.CssClass = "linkSmallBold";
author.Text = post.Username;
author.NavigateUrl = Globals.UrlUserProfile + post.Username;
label.Controls.Add(author);
// Whitespace
label.Controls.Add(new LiteralControl(" "));
// Special formatting for the date
Label datePosted = new Label();
datePosted.CssClass = "normalTextSmall";
if (Page.Request.IsAuthenticated) {
datePosted.Text = Users.AdjustForTimezone(post.PostDate, ((User) Users.GetUserInfo(Context.User.Identity.Name, true)).Timezone, PostDateTimeFormat);
} else {
datePosted.Text = "Posted: " + post.PostDate.ToString(PostDateTimeFormat);
}
label.Controls.Add(datePosted);
td.Controls.Add(label);
} else {
// Set the style on the cell we render in
td.CssClass = "threadTitle";
td.Controls.Add(RenderDetailedThreadTitle(post));
}
}
// *********************************************************************
// RenderDetailedThreadTitle
//
/// <summary>
/// Renders the thread title used when a thread body is displayed
/// </summary>
///
// ********************************************************************/
private Control RenderDetailedThreadTitle(Post post) {
Table table;
TableRow tr;
TableCell td;
Image image;
// Create the table
table = new Table();
table.CellPadding = 0;
table.CellSpacing = 2;
// Get the user that created the post
postUser = Users.GetUserInfo(post.Username, false);
// Create the row
tr = new TableRow();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -