Optionally provide private feedback to help us improve this article...

Thank you for your feedback!


Creating a custom forum view via a user control

This article details how to create a custom view for your forums. This can be helpful if you wish to display your forums in a different way than that offered by InstantForum. This example uses a custom user control to make it easy for you to include this custom user control on any InstantForum page.

This example renders all top level forum categories and then each forum within each category. Below each forum the last 10 topics will be displayed from the forum and all child forums. For further information on how to include custom user controls within InstantForum please see Adding custom user controls to InstantForum.

The User Control

LatestForumPosts.ascx

The user control will contain 3 ASP.NET repeater controls. ctlForumGroups is used to render the forum categories, ctlForums is used to render the forums within each category and ctlTopics is used to render the topics within each forum.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="LatestForumPosts.ascx.cs" Inherits="Skins_InstantASP_CustomControls_LatestForumPosts" %>
<%@ Register tagPrefix="InstantASP" Namespace="InstantASP.Common.UI.WebControls" Assembly="InstantASP.Common.UI" %>
<%@ Register tagPrefix="InstantForum" Namespace="InstantASP.InstantForum.UI.Controls" Assembly="InstantASP.InstantForum.UI" %>
<%@ Register tagPrefix="InstantForumWebControls" Namespace="InstantASP.InstantForum.UI.WebControls" Assembly="InstantASP.InstantForum.UI" %>

<InstantASP:Repeater id="ctlForumGroups" EnableViewState="false" runat="Server">
<ItemTemplate>
<InstantASP:PanelBar id="ctlPanelBar" TableName="pnlForums" runat="Server">
<InstantASP:Panel ID="pnlForums" CssClass="margin" runat="server">
<InstantASP:Repeater id="ctlForums" EnableViewState="false" runat="Server">
<ItemTemplate>

<div class="row">
<div class="float-left">
<h3>
<InstantASP:HyperLink ID="hypForumTitlte" runat="server" />
</h3>
</div>
<div class="float-right">
<strong>
Topics: <InstantASP:Literal ID="lblTotalTopics" runat="server" />,
Replies: <InstantASP:Literal ID="lblTotalReplies" runat="server" />
</strong>
</div>
</div>
<div class="row">
<InstantASP:Repeater id="ctlTopics" EnableViewState="false" runat="Server">
<HeaderTemplate>
<span style="font-size: 8pt; text-transform: uppercase;">Latest Topics</span><br />
</HeaderTemplate>
<ItemTemplate>
<div class="row">
<div class="float-left">
- <InstantASP:HyperLink ID="hypTopicTitlte" runat="server" /><br />
</div>
<div class="float-right">
<InstantASP:Literal ID="lblLastPostDate" runat="server" />
</div>
</div>
<br />
</ItemTemplate>
</InstantASP:Repeater>
<br />
</div>

</ItemTemplate>
</InstantASP:Repeater>
</InstantASP:Panel>
</InstantASP:PanelBar>
<InstantASP:Spacer id="ctlSpacer1" runat="Server"/>
</ItemTemplate>
</InstantASP:Repeater>

LatestForumPosts.ascx.cs

The code-behind for the user control simply sets-up the various repeater controls with the appropriate data as shown below...

using System;
using InstantASP.InstantForum.Business;
using InstantASP.InstantForum.Components;
using InstantASP.InstantForum.Collections;
using InstantASP.Common.UI.WebControls;
using InstantASP.InstantForum.HttpContext;

public partial class Skins_InstantASP_CustomControls_LatestForumPosts : System.Web.UI.UserControl
{

private Forums f;
private Forum _forum;
private ForumCollection _forums;
private ForumContext _forumContext = ForumContext.Current;

protected void Page_Load(object sender, EventArgs e)
{

ctlForumGroups = (Repeater)this.FindControl("ctlForumGroups");
ctlForumGroups.ItemCreated += ctlForumGroups_ItemCreated;
ctlForumGroups.ItemDataBound += ctlForumGroups_ItemDataBound;

if (!Page.IsPostBack)
BindData();

}

#region "Private Methods"

private void BindData()
{

f = new InstantASP.InstantForum.Business.Forums(_forumContext.CurrentUser.UserID);

// we don't have a forum, display index
if (_forum == null)
{
// bind collection from database
_forums = f.SelectForumCategories();

}
else
{
// we are within a forum
if (_forum.IsCategory)
{
_forums = new ForumCollection();
_forums.Add(_forum);

}
else
{
// bind forum collection
_forums = ReturnSubForumCollection();

}
}

// do we have a collection?
if (_forums != null)
{

if (_forums.Count > 0)
{

// bind groups
if (ctlForumGroups != null)
{
ctlForumGroups.DataSource = _forums;
ctlForumGroups.DataBind();
}

}
else
{
ctlForumGroups.Visible = false;
}

}
else
{
ctlForumGroups.Visible = false;
}

}

private ForumCollection ReturnSubForumCollection()
{

// create forum, this acts as a dummy group to hold any sub forums
Forum SubForum = new Forum();
SubForum.IsCategory = true;
SubForum.Expanded = true;

// ensure the panel bar displaying the sub forums is expanded by default
if ((_forum != null))
{
SubForum.ForumID = _forum.ForumID;
SubForum.SubForums = _forum.SubForums;
SubForum.NavigateURL = _forum.NavigateURL;
SubForum.Name = _forum.Name;
}

// create forum collection and add false forum
ForumCollection ForumCollection = new ForumCollection();
ForumCollection.Add(SubForum);

// finally return forum to bind to repeater
return ForumCollection;

}


#endregion

#region "Repeater Events"

public void ctlForumGroups_ItemCreated(object Sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{

if (e.Item.ItemType == System.Web.UI.WebControls.ListItemType.Item | e.Item.ItemType == System.Web.UI.WebControls.ListItemType.AlternatingItem)
{

// find spacer control
Spacer ctlSpacer1 = (Spacer)e.Item.FindControl("ctlSpacer1");

if (_forums != null)
{
if (e.Item.ItemIndex == _forums.Count - 1)
{
ctlSpacer1.Visible = false;
}
}

}

}

public void ctlForumGroups_ItemDataBound(object Sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{

if (e.Item.ItemType == System.Web.UI.WebControls.ListItemType.Item | e.Item.ItemType == System.Web.UI.WebControls.ListItemType.AlternatingItem)
{

// get forum
Forum forum = (Forum)e.Item.DataItem;

// setup panel bar to hold topics table
PanelBar ctlPanelBar = (PanelBar)e.Item.FindControl("ctlPanelBar");
ctlPanelBar.Culture = _forumContext.CurrentCulture;
ctlPanelBar.CookiePrefix = _forumContext.CurrentSettings.CookiePrefix();
ctlPanelBar.UniqueIdentity = forum.ForumID.ToString();
ctlPanelBar.TextNonLocalized = InstantASP.Common.Utils.Text.Truncate(forum.Name, _forumContext.CurrentSettings.SubjectTruncation());

// if we have a description for the category use this for the tooltip
if (!string.IsNullOrEmpty(forum.Description))
{
ctlPanelBar.ToolTipNonLocalized = forum.Description;
}
else
{
ctlPanelBar.ToolTip = "ForumGroups_PanelBarLinkToolTip";
ctlPanelBar.ToolTipReplaceText = forum.Name;
}

ctlPanelBar.NavigateUrl = _forumContext.InstallURL + InstantASP.InstantForum.Globals.Paths.Group(forum.ForumID);

if (forum.Expanded)
{
ctlPanelBar.Expanded = true;
}
else
{
ctlPanelBar.Expanded = false;
}

Repeater ctlForums = (Repeater)ctlPanelBar.FindControl("ctlForums");
ctlForums.ItemDataBound += ctlForums_ItemDataBound;

// finally bind forum data
ForumCollection childForums = null;
if (_forum != null)
{
childForums = _forum.SubForums;
}
else
{
childForums = forum.SubForums;
}

// ensure we have data
if (childForums.Count > 0)
{
ctlForums.DataSource = childForums;
ctlForums.DataBind();

}

}

}

public void ctlForums_ItemDataBound(object Sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{

if (e.Item.ItemType == System.Web.UI.WebControls.ListItemType.Item | e.Item.ItemType == System.Web.UI.WebControls.ListItemType.AlternatingItem)
{

// get forum
Forum forum = (Forum)e.Item.DataItem;

HyperLink hypForumTitlte = (HyperLink)e.Item.FindControl("hypForumTitlte");
hypForumTitlte.TextNonLocalized = forum.Name;
hypForumTitlte.NavigateUrl = _forumContext.InstallURL + InstantASP.InstantForum.Globals.Paths.Forum(forum.ForumID);

Literal lblTotalTopics = (Literal)e.Item.FindControl("lblTotalTopics");
lblTotalTopics.Text = InstantASP.Common.Formatters.Numeric.FormatNum(forum.TotalTopics);

Literal lblTotalReplies = (Literal)e.Item.FindControl("lblTotalReplies");
lblTotalReplies.Text = InstantASP.Common.Formatters.Numeric.FormatNum(forum.TotalPosts);

// repeater to bind topics to
Repeater ctlTopics = (Repeater)e.Item.FindControl("ctlTopics");
ctlTopics.ItemDataBound += ctlTopics_ItemDataBound;

// get data to bind to topics repeater

InstantASP.InstantForum.Collections.ForumCollection forums =
f.RecurseForwards(forum.ForumID);

if (forums != null)
{
forums.Add(forum);
}

SearchEventArgs args = new SearchEventArgs();
args.ForumIDs = InstantASP.Common.Utils.Array.StringToIntArray(
forums.IdentitiesAsString(false, ','), ","); ;
args.SortBy = "LastPosterDate";
args.SortOrder = InstantASP.Common.Enumerations.EnumSortOrder.DESC;
args.ParentID = 0;
args.MaxResults = 10;

InstantASP.InstantForum.Collections.TopicCollection topics =
InstantASP.InstantForum.Business.Topics.SelectTopics(args);

if (topics != null)
{
if (topics.Count > 0)
{
ctlTopics.DataSource = topics;
ctlTopics.DataBind();
}
else
{
ctlTopics.Visible = false;
}
}
else
{
ctlTopics.Visible = false;
}

}

}

public void ctlTopics_ItemDataBound(object Sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{

if (e.Item.ItemType == System.Web.UI.WebControls.ListItemType.Item | e.Item.ItemType == System.Web.UI.WebControls.ListItemType.AlternatingItem)
{

// get topic
Topic topic = (Topic)e.Item.DataItem;

// topic title
HyperLink hypTopicTitlte = (HyperLink)e.Item.FindControl("hypTopicTitlte");
hypTopicTitlte.TextNonLocalized = topic.Title;
hypTopicTitlte.NavigateUrl = _forumContext.InstallURL + InstantASP.InstantForum.Globals.Paths.Topic(topic.PostID);

// last post date for topic
Literal lblLastPostDate = (Literal)e.Item.FindControl("lblLastPostDate");
lblLastPostDate.Text = InstantASP.Common.Formatters.Date.FormatDate(topic.LastPosterDate, _forumContext.CurrentDateTimeFormat, _forumContext.CurrentTimeZoneOffSet, _forumContext.CurrentUser.ObserveDaylightSavingTime, _forumContext.CurrentCulture, true, true, false, false);

}

}

#endregion
}

Once you've created or downloaded the custom user control from the link below we would suggest copying the LatestForumPosts.ascx and LatestForumPosts.ascx.cs files into your InstantForum skin folder. For example Skins/{YourSkinName}/CustomControls/LatestForumPosts.ascx

You can then include this custom view on any InstantForum page. For example if you wanted to include this as a replacement for the regular forum view offered by InstantForum on the homepage you would need to open Skins/{YourSkinName}/Default.ascx within NotePad or Visual Studio

Register the custom user control as shown below...

<%@ Register Src="~/Skins/YourSkinName/CustomControls/LatestForumPosts.ascx" TagPrefix="uc1" TagName="LatestForumPosts" %> 

Then include the control within the mark-up within Default.ascx where appropriate...

<uc1:latestforumposts runat="server" id="LatestForumPosts" />

The Result

The code in this example will produce a view similar to that shown below...

​Download The Control

You can download this example user control from the link below.

Attachments


LatestForumPosts.zip 3.00 KB, 328 views