This week's Tip of the Week blog post is going to sample a custom
download list control. The difference between this control and the
built-in one is that the custom one is going to display
the downloadable items in separate tables, broken down by parent
libraries to which they belong. Bellow you can see the resulting look
and feel of the control:
To achieve this we will need to create a custom control and provide a control template for this control. In this sample I have inherited from DownloadList to utilize the existing ability to select libraries from which we wish to display items for download. What we will do is to create a custom template which has two nested repeaters. The outer one will display library name and the inned one will display content items belonging to his library. Bellow is the sample code for the CustomDonwloadList control:
using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Globalization;
using
System.Linq;
using
System.Web.UI.WebControls;
using
Telerik.Cms.Engine;
using
Telerik.Cms.Engine.ContentViewFiltering;
using
Telerik.Cms.Engine.WebControls;
using
Telerik.Libraries;
/// <summary>
/// Summary description for CustomDownloadList
/// </summary>
public
class
CustomDownloadList: DownloadList
{
//set template path for the control template
public
override
string
ItemListTemplatePath
{
get
{
return
"~/CustomControls/ControlTemplates/CustomDonwloadList.ascx"
;
}
set
{
base
.ItemListTemplatePath = value;
}
}
public
override
string
ProviderName
{
get
{
return
"Libraries"
;
}
set
{
base
.ProviderName = value;
}
}
//here we populate our libraries repeater with selected libraries
protected
override
void
CreateContentList()
{
ContentFilterBuilder filterBuilder =
new
ContentFilterBuilder(
this
);
libraryManager =
new
LibraryManager();
IList libraries =
null
;
Guid[] parentIds = filterBuilder.ParseParentsFilter();
if
(parentIds.Count()>0)
{
List<ILibrary> libs =
new
List<ILibrary>();
foreach
(Guid id
in
parentIds)
{
libs.Add(libraryManager.GetLibrary(id));
}
libraries = libs.ToList();
}
else
{
libraries = libraryManager.GetAllLibraries(
"Image"
,
false
);
}
//sort libraries in ascending order by name
IQueryable<ILibrary> librariesQ = libraries.Cast<ILibrary>().AsQueryable<ILibrary>();
var sortedLibraries = from list
in
librariesQ
orderby list.Name
select list;
LibrariesRepeater.ItemDataBound+=
new
RepeaterItemEventHandler(LibrariesRepeater_ItemDataBound);
LibrariesRepeater.DataSource = sortedLibraries.ToList();
LibrariesRepeater.DataBind();
}
//for each selected library create the table containing content items
void
LibrariesRepeater_ItemDataBound(
object
sender, RepeaterItemEventArgs e)
{
if
(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
ILibrary library = (ILibrary)e.Item.DataItem;
if
(library.ItemsCount > 0)
{
Literal LibraryName = (Literal)e.Item.FindControl(
"LibraryName"
);
Repeater ItemsRepeater = (Repeater)e.Item.FindControl(
"itemsRepeater"
);
if
(ItemsRepeater !=
null
&& LibraryName!=
null
)
{
LibraryName.Text = library.Name;
IList items = library.GetItems();
ItemsRepeater.ItemDataBound +=
new
RepeaterItemEventHandler(ItemsRepeater_ItemDataBound);
ItemsRepeater.DataSource = items;
ItemsRepeater.DataBind();
}
}
}
}
//set meta data for each item displayed in the downloads table
void
ItemsRepeater_ItemDataBound(
object
sender, RepeaterItemEventArgs e)
{
if
(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
HyperLink DownloadLink = (HyperLink)e.Item.FindControl(
"DownloadLink"
);
Literal Title = (Literal)e.Item.FindControl(
"Title"
);
Literal Description = (Literal)e.Item.FindControl(
"Description"
);
Literal Extension = (Literal)e.Item.FindControl(
"Extension"
);
Label Author = (Label)e.Item.FindControl(
"Author"
);
Literal UploadDate = (Literal)e.Item.FindControl(
"UploadDate"
);
Literal Size = (Literal)e.Item.FindControl(
"Size"
);
Repeater Tags = (Repeater)e.Item.FindControl(
"Tags"
);
HyperLink FileFileDownloadLink = (HyperLink)e.Item.FindControl(
"FileDownloadLink"
);
IContent contentItem = (IContent)e.Item.DataItem;
if
(contentItem.MimeType.StartsWith(
"Video"
,
true
, CultureInfo.InvariantCulture))
{
DownloadLink.NavigateUrl =
base
.ResolveUrl(
string
.Format(
"{0}?download=true"
, contentItem.UrlWithExtension));
}
else
{
DownloadLink.NavigateUrl =
base
.ResolveUrl(contentItem.UrlWithExtension);
}
FileFileDownloadLink.NavigateUrl =
base
.ResolveUrl(
string
.Format(
"{0}?download=true"
, contentItem.UrlWithExtension));
Title.Text = contentItem.GetMetaData(
"Name"
)
as
string
;
Description.Text = contentItem.GetMetaData(
"Description"
)
as
string
;
Extension.Text = contentItem.GetMetaData(
"Extension"
)
as
string
;
Author.Text = contentItem.GetMetaData(
"Author"
)
as
string
;
UploadDate.Text = contentItem.DateCreated.ToShortDateString();
Size.Text = contentItem.GetMetaData(
"Size"
).ToString();
long
num;
long
.TryParse(Size.Text,
out
num);
Size.Text = LibraryHelper.FormatSizeString(num);
Tags.ItemDataBound +=
new
RepeaterItemEventHandler(Tags_ItemDataBound);
Tags.DataSource = libraryManager.GetTags(contentItem.ID);
Tags.DataBind();
}
}
void
Tags_ItemDataBound(
object
sender, RepeaterItemEventArgs e)
{
if
((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
ITag dataItem = (ITag)e.Item.DataItem;
HyperLink link = (HyperLink)e.Item.FindControl(
"tagLink"
);
if
(link !=
null
)
{
link.Text = dataItem.TagName;
link.NavigateUrl =
this
.GetTagUrl(dataItem,
this
.ItemListUrl);
}
}
}
//get reference to the libraries repeater from control template
public
Repeater LibrariesRepeater
{
get
{
return
base
.ListContainer.GetControl<Repeater>(
"librariesRepeater"
,
false
, Telerik.Framework.Web.TraverseMethod.BreadthFirst);
}
set
{
LibrariesRepeater = value;
}
}
private
LibraryManager libraryManager;
}
Now we need to provide the markup for our control template. I am going to reuse the one from the Download List Table View mode template:
<%@ Control Language="C#" %>
<%--content view controls have a required Repeater control with ID="repeater" add one and set it to not visible--%>
<
asp:Repeater
ID
=
"repeater"
runat
=
"server"
Visible
=
"false"
></
asp:Repeater
>
<
telerik:CssFileLink
ID
=
"CssFileLink1"
FileName
=
"~/CustomControls/ControlTemplates/librariesCommonLayout.css"
Media
=
"screen"
runat
=
"server"
/>
<
asp:Repeater
ID
=
"librariesRepeater"
runat
=
"server"
>
<
ItemTemplate
>
<
p
><
asp:Literal
ID
=
"LibraryName"
runat
=
"server"
></
asp:Literal
></
p
>
<
asp:Repeater
ID
=
"itemsRepeater"
runat
=
"server"
>
<
HeaderTemplate
>
<
table
class
=
"sf_libraryGrid"
>
<
thead
>
<
tr
>
<
th
scope
=
"col"
id
=
"TitleWrap"
runat
=
"server"
><
asp:Literal
ID
=
"Literal1"
runat
=
"server"
Text="<%$Resources:Items_Title %>"></
asp:Literal
></
th
>
<
th
scope
=
"col"
id
=
"ExtWrap"
runat
=
"server"
><
asp:Literal
ID
=
"Literal2"
runat
=
"server"
Text="<%$Resources:Items_Extension %>"></
asp:Literal
></
th
>
<
th
scope
=
"col"
id
=
"AuthorWrap"
runat
=
"server"
><
asp:Literal
ID
=
"Literal3"
runat
=
"server"
Text="<%$Resources:Items_Author %>"></
asp:Literal
></
th
>
<
th
scope
=
"col"
id
=
"UploadDateWrap"
runat
=
"server"
><
asp:Literal
ID
=
"Literal4"
runat
=
"server"
Text="<%$Resources:Items_UploadDate %>"></
asp:Literal
></
th
>
<
th
scope
=
"col"
id
=
"SizeWrap"
runat
=
"server"
><
asp:Literal
ID
=
"Literal5"
runat
=
"server"
Text="<%$Resources:Items_Size %>"></
asp:Literal
></
th
>
<
th
scope
=
"col"
id
=
"TagWrap"
runat
=
"server"
><
asp:Literal
ID
=
"Literal6"
runat
=
"server"
Text="<%$Resources:Items_Tags %>"></
asp:Literal
></
th
>
<
th
scope
=
"col"
id
=
"DownloadLinkWrap"
runat
=
"server"
></
th
>
</
tr
>
</
thead
>
<
tbody
>
</
HeaderTemplate
>
<
ItemTemplate
>
<
tr
>
<
th
id
=
"TitleWrap"
runat
=
"server"
scope
=
"row"
class
=
"sf_docTitle"
>
<
asp:HyperLink
ID
=
"DownloadLink"
runat
=
"server"
>
<
asp:Literal
ID
=
"Title"
runat
=
"server"
></
asp:Literal
>
</
asp:HyperLink
>
<
asp:Literal
ID
=
"Description"
runat
=
"server"
/>
</
th
>
<
td
id
=
"ExtWrap"
runat
=
"server"
><
asp:Literal
id
=
"Extension"
runat
=
"server"
></
asp:Literal
></
td
>
<
td
id
=
"AuthorWrap"
runat
=
"server"
><
asp:Label
id
=
"Author"
runat
=
"server"
></
asp:Label
></
td
>
<
td
id
=
"UploadDateWrap"
runat
=
"server"
class
=
"sf_date"
>
<
asp:Literal
ID
=
"UploadDate"
runat
=
"server"
/>
</
td
>
<
td
id
=
"SizeWrap"
runat
=
"server"
class
=
"sf_size"
><
asp:Literal
id
=
"Size"
runat
=
"server"
></
asp:Literal
></
td
>
<
td
id
=
"TagWrap"
runat
=
"server"
>
<
asp:Repeater
id
=
"Tags"
runat
=
"server"
>
<
ItemTemplate
>
<
asp:HyperLink
ID
=
"tagLink"
runat
=
"server"
></
asp:HyperLink
>
</
ItemTemplate
>
</
asp:Repeater
>
</
td
>
<
td
id
=
"DownloadLinkWrap"
runat
=
"server"
><
asp:HyperLink
ID
=
"FileDownloadLink"
runat
=
"server"
Text="<%$Resources:Items_Download %>" /></
td
>
</
tr
>
</
ItemTemplate
>
<
FooterTemplate
>
</
tbody
>
</
table
>
</
FooterTemplate
>
</
asp:Repeater
>
</
ItemTemplate
>
</
asp:Repeater
>
<
telerik:Pager
ID
=
"pager1"
runat
=
"server"
>
<
LayoutTemplate
>
<
asp:Repeater
ID
=
"PageRepeaterLinkButton"
runat
=
"server"
>
<
HeaderTemplate
>
<
ol
class
=
"sf_pager"
>
<
li
><
asp:LinkButton
ID
=
"PreviousPage"
runat
=
"server"
Text="<%$Resources:Items_PreviousPage %>"></
asp:LinkButton
></
li
>
</
HeaderTemplate
>
<
ItemTemplate
>
<
li
>
<
asp:LinkButton
ID
=
"SingleItem"
runat
=
"server"
/>
</
li
>
</
ItemTemplate
>
<
FooterTemplate
>
<
li
><
asp:LinkButton
ID
=
"NextPage"
runat
=
"server"
Text="<%$Resources:Items_NextPage %>"></
asp:LinkButton
></
li
>
</
ol
>
</
FooterTemplate
>
</
asp:Repeater
>
<
asp:Repeater
ID
=
"PageRepeaterHyperLink"
runat
=
"server"
>
<
HeaderTemplate
>
<
ol
class
=
"sf_pager"
>
<
li
><
asp:HyperLink
ID
=
"PreviousPage"
runat
=
"server"
Text="<%$Resources:Items_PreviousPage %>"></
asp:HyperLink
></
li
>
</
HeaderTemplate
>
<
ItemTemplate
>
<
li
>
<
asp:HyperLink
ID
=
"SingleItem"
runat
=
"server"
/>
</
li
>
</
ItemTemplate
>
<
FooterTemplate
>
<
li
><
asp:HyperLink
ID
=
"NextPage"
runat
=
"server"
Text="<%$Resources:Items_NextPage %>"></
asp:HyperLink
></
li
>
</
ol
>
</
FooterTemplate
>
</
asp:Repeater
>
</
LayoutTemplate
>
</
telerik:Pager
>
Finally all you have to do is add the control to your Sitefinity toolbox.
You can download the control source code, markup for template, style sheet and localization resources file from this link: CustomDownloadList