📄 postthreaded.cs
字号:
// Create the cell where the actual data goes
td = new TableCell();
td.VerticalAlign = VerticalAlign.Top;
// Add the location anchor
td.Controls.Add(new LiteralControl("<a name=\"" + post.PostID + "\"/>"));
// Display the subject
Label label = new Label();
label.CssClass = "normalTextSmallBold";
label.Text = post.Subject;
td.Controls.Add(label);
// Line Break
td.Controls.Add(new LiteralControl("<br>"));
// Label for data under subject
label = new Label();
label.CssClass = "normalTextSmall";
// Whitespace
label.Controls.Add(new LiteralControl("Posted by: "));
// Author
HyperLink author = new HyperLink();
author.Text = post.Username;
author.NavigateUrl = Globals.UrlUserProfile + post.Username;
label.Controls.Add(author);
// Whitespace
label.Controls.Add(new LiteralControl(" "));
// Date
Label datePosted = new Label();
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);
// Add existing line and line break
td.Controls.Add(label);
td.Controls.Add(new LiteralControl("<br>"));
// Add Reply Link
label = new Label();
label.CssClass = "threadDetailTextSmall";
HyperLink postReply = new HyperLink();
postReply.Text = "Reply";
postReply.NavigateUrl = Globals.UrlReplyToPost + post.PostID;
label.Controls.Add(postReply);
/*
// Whitespace
label.Controls.Add(new LiteralControl(" | "));
// Add new thread Link
HyperLink newThread = new HyperLink();
newThread.Text = "New Thread";
newThread.NavigateUrl = Globals.UrlAddNewPost + post.ForumID;
label.Controls.Add(newThread);
*/
// Only add the Parent link if we have a parent
if (post.ParentID != post.PostID) {
// Whitespace
label.Controls.Add(new LiteralControl(" | "));
HyperLink parentPost = new HyperLink();
parentPost.Text = "Parent";
parentPost.NavigateUrl = Globals.UrlShowPost + post.PostID + "&View=Threaded&ThreshHold=" + (Convert.ToInt32(post.PostLevel) + 1) + "#" + post.ParentID;
label.Controls.Add(parentPost);
}
td.Controls.Add(label);
tr.Controls.Add(td);
table.Controls.Add(tr);
return table;
}
// *********************************************************************
// HandleIndentingForThreaded
//
/// <summary>
/// Used to indent thread items based on the nested depth of the thread
/// relative to its parent.
/// </summary>
///
// ********************************************************************/
public void HandleIndentingForThreaded(Object sender, EventArgs e) {
Label indent;
RepeaterItem container;
Post post;
// Bound to type Label
indent = (Label) sender;
// Get the RepeaterItem containing the data
container = (RepeaterItem) indent.NamingContainer;
// Original class type we're bound to
post = (Post) container.DataItem;
// If we're the first item don't indent
if (container.ItemIndex == 0) {
return;
}
// Perform nesting. This gets written within a TableCell
for (int i = threadedStartPostLevel; i < post.PostLevel; i++ ) {
indent.Text += " ";
}
}
// *********************************************************************
// ApplyTemplates
//
/// <summary>
/// Applies templates to control the ui generated by the control. If no
/// template is specified a custom template is used. If a template is found
/// in the skins directory, that template is loaded and used. If a user defined
/// template is found, that template takes priority.
/// </summary>
///
// ********************************************************************/
private void ApplyTemplates(Repeater repeater) {
string pathToHeaderTemplate;
string pathToItemTemplate;
string pathToFooterTemplate;
string keyForHeaderTemplate;
string keyForItemTemplate;
string keyForFooterTemplate;
// Are we using skinned template?
if (Page != null) {
// Set the file paths to where the templates should be found
keyForHeaderTemplate = Globals.Skin + "/Templates/ThreadView-Header.ascx";
keyForItemTemplate = Globals.Skin + "/Templates/ThreadView-Item.ascx";
keyForFooterTemplate = Globals.Skin + "/Templates/ThreadView-Footer.ascx";
// Set the file paths to where the templates should be found
pathToHeaderTemplate = Globals.ApplicationVRoot + "/Skins/" + keyForHeaderTemplate;
pathToItemTemplate = Globals.ApplicationVRoot + "/skins/" + keyForItemTemplate;
pathToFooterTemplate = Globals.ApplicationVRoot + "/skins/" + Globals.Skin + keyForFooterTemplate;
// Attempt to get the skinned header template
if (repeater.HeaderTemplate == null)
repeater.HeaderTemplate = Globals.LoadSkinnedTemplate(pathToHeaderTemplate, keyForHeaderTemplate, Page);
// Attempt to get the skinned item template
if (repeater.ItemTemplate == null)
repeater.ItemTemplate = Globals.LoadSkinnedTemplate(pathToItemTemplate,keyForItemTemplate, Page);
// Attempt to get the footer template
if (repeater.FooterTemplate == null)
repeater.FooterTemplate = Globals.LoadSkinnedTemplate(pathToFooterTemplate, keyForFooterTemplate, Page);
}
// Item template
if (repeater.ItemTemplate == null)
repeater.ItemTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(BuildItemTemplate));
}
// *********************************************************************
// CreateChildControls
//
/// <summary>
/// Override CreateChildControls
/// </summary>
///
// ********************************************************************/
protected override void CreateChildControls() {
// Make sure a postID was specified
if (PostID == -1)
throw new Exception("Attempted to create the ThreadDiaplay control without passing in either a PostID.");
// Create the threadedRepeater Repeater
threadedRepeater = new Repeater();
// Apply templates
ApplyTemplates(threadedRepeater);
// We're threaded so we only want to show children of the PostID
// threadedRepeater.DataSource = GetChildrenByPostID();
threadedRepeater.DataSource = Posts.GetThreadByPostID(PostID);
// DataBind
threadedRepeater.DataBind();
this.Controls.Add(threadedRepeater);
}
private PostCollection GetChildrenByPostID() {
PostCollection posts;
PostCollection threaded = new PostCollection();
Stack threadStack = new Stack();
// Get posts for the post id
posts = Posts.GetThreadByPostID(PostID);
// Push the PostID on to the stack
threadStack.Push(PostID);
foreach (Post post in posts) {
if (post.PostID != (int) threadStack.Peek()) {
if (threadStack.Contains((int)post.ParentID)) {
threadStack.Push(post.PostID);
threaded.Add(post);
}
} else {
threaded.Add(post);
}
}
return threaded;
}
// *********************************************************************
// PostID
//
/// <summary>
/// Specifies the ID of the Post whose thread you wish to view.
/// </summary>
/// <remarks>If this property is not set and the ThreadID property is not set, an Exception is
/// thrown. If this property is set, the RightArrowImageUrl will be displayed for the appropriate
/// Post in the thread.
/// </remarks>
///
// ********************************************************************/
public int PostID {
get {
if (ViewState["postID"] == null) return -1;
return (int) ViewState["postID"];
}
set {
if (value < 0)
ViewState["postID"] = 0;
else
ViewState["postID"] = value;
}
}
// *********************************************************************
// PostDateTimeFormat
//
/// <summary>
/// Specifies the date/time format to display the post date in.
/// The string should contain valid DateTimeFormatInfo characters. For example, to display the
/// date range as MM/DD/YYYY - HH:MM AM/PM, use the string: MM/dd/yyyy - HH:mm tt
/// </summary>
///
// ********************************************************************/
[
Category("Style"),
Description("Specifies the date/time format to display the post date in.")
]
public String PostDateTimeFormat {
get {
if (ViewState["postDateTimeFormat"] == null) return defaultPostDateTimeFormat;
return (String) ViewState["postDateTimeFormat"];
}
set { ViewState["postDateTimeFormat"] = value; }
}
// *********************************************************************
// Threshhold
//
/// <summary>
/// Controls the depth at which the body of the thread is no longer displayed
/// </summary>
///
// ********************************************************************/
[
Description("Controls the depth at which the body of the thread is no longer displayed.")
]
public int Threshhold {
get { return this.threshHold; }
set { threshHold = value; }
}
// *********************************************************************
// ThreadItemTemplate
//
/// <summary>
/// Allows user to define the template for the thread title when the body
/// is shown
/// </summary>
///
// ********************************************************************/
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate ThreadItemTemplate {
get { return threadItemTemplate; }
set { threadItemTemplate = value; }
}
// *********************************************************************
// ThreadBelowThreshHoldItemTemplate
//
/// <summary>
/// Allows user to define the template used to render thread titles
/// below the defined threshold (body of thread is not shown)
/// </summary>
///
// ********************************************************************/
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate ThreadBelowThreshHoldItemTemplate {
get { return threadBelowThreshHoldItemTemplate; }
set { threadBelowThreshHoldItemTemplate = value; }
}
// *********************************************************************
// BodyTemplate
//
/// <summary>
/// Template used to show body of thread
/// </summary>
///
// ********************************************************************/
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate BodyTemplate {
get { return bodyTemplate; }
set { bodyTemplate = value; }
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -