Whatever breath I am getting from hectic office work, I am spending on small tasks
such as learning/ exploring few new/old asp.net controls such as ListView, DetailsView
etc and how they can be integrated with SharePoint. I will be sharing my findings
(rather I should say learnings) along with the working examples that I created in
this post.
Note that these controls have been explored before by many people and hence don’t
forget to google for them. However, I cannot miss to mention two people who has
discovered near about all the hidden SharePoint controls making SharePoint development
so easy.
1. CAML girl Karine Bosch
2. Zevenseas Robin
Robin loves to explore the OOB SharePoint controls and has blogged about SharePoint
controls which Karine has missed. Search through his posts and you will come to
know many SharePoint hidden gems
My focus however is more towards asp.net controls and today I will be writing on
ListView control. It is new addition in asp.net 3.5 framework. ListView
control is very powerful, flexible and it provides greater control than its counterparts
GridView and DataList. It possess capabilities of both GridView and DataList controls
to a such extend that I don’t think I will use GridView or DataList henceforth.
I created three examples as follows.
A. ListView control with
SPDataSource
This is no code behind implementation. Here SPDataSource acts as DataSource to ListView control. If you are not aware
of SPDataSource control, have a look at Chris O’brien’s series of posts
Code:
<style type="text/css">
.TableCSS
{
border-style: solid;
border: 1px solid #507CD1;
width: 400px;
}
.TableCSS td
{
height: 25px;
}
.TableHeader
{
background-color: #507CD1;
color: Black;
font-weight: bold;
font-family: calibri;
font-size: 16px;
}
.noramlRowData
{
background-color: #EFF3FB;
color: Black;
font-size: 15px;
font-weight: normal;
font-family: calibri;
}
.alternatingRowData
{
background-color: White;
color: Black;
font-size: 15px;
font-weight: normal;
font-family: calibri;
}
.dataPager
{
color: BLUE;
background-color: White;
text-align: center;
font-size: 14px;
font-family: calibri;
}
</style>
<SharePoint:SPDataSource runat="server"
ID="dsProducts"
DataSourceMode="List"
SelectCommand="<Query><OrderBy><FieldRef
Name='ID'/></OrderBy></Query>">
<SelectParameters>
<asp:Parameter Name="ListName"
DefaultValue="Products"
/>
</SelectParameters>
</SharePoint:SPDataSource>
<asp:ListView
ID="listView"
runat="server"
DataSourceID="dsProducts">
<LayoutTemplate>
<table
class="TableCSS"
cellpadding="0"
cellspacing="0">
<tr class="TableHeader">
<td align="center">
Product ID
</td>
<td>
Product Name
</td>
<td>
Product Cost
</td>
</tr>
<tr id="ItemPlaceholder"
runat="server">
</tr>
<tr>
<td colspan="3"
class="dataPager">
<asp:DataPager ID="DataPager1"
runat="server"
PageSize="5">
<Fields>
<asp:NextPreviousPagerField
ButtonType="Link"
ShowFirstPageButton="false"
ShowPreviousPageButton="true"
ShowNextPageButton="False"
PreviousPageText="<<
Previous" RenderDisabledButtonsAsLabels="false" />
<asp:NumericPagerField
/>
<asp:NextPreviousPagerField
ButtonType="Link"
ShowLastPageButton="false"
ShowNextPageButton="true"
ShowPreviousPageButton="False"
FirstPageText="Previous"
NextPageText="Next >>"
RenderDisabledButtonsAsLabels="false"
/>
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr class="noramlRowData">
<td align="center">
<asp:Label
ID="Label1" runat="server" Text='<%# Eval("ID")%>'>
</asp:Label>
</td>
<td>
<asp:Label
ID="Label2" runat="server" Text='<%# Eval("Title")%>'>
</asp:Label>
</td>
<td>
रु <asp:Label ID="Label3" runat="server" Text='<%# Eval("Cost")%>'>
</asp:Label>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr class="alternatingRowData">
<td align="center">
<asp:Label
ID="Label1" runat="server" Text='<%# Eval("ID")%>'>
</asp:Label>
</td>
<td>
<asp:Label
ID="Label2" runat="server" Text='<%# Eval("Title")%>'>
</asp:Label>
</td>
<td>
रु <asp:Label ID="Label3" runat="server" Text='<%# Eval("Cost")%>'>
</asp:Label>
</td>
</tr>
</AlternatingItemTemplate>
</asp:ListView>
|
Output:
B. ListView control with SPDataSource
(Data grouping - rows flowing in multiple columns)
Unlike above example which matches GridView behavior, this example matches DataList
control behavior where you can control the flow of rows into multiple columns.
Code:
<style type="text/css">
.ImagePageHeader
{
width: 100%;
text-align: center;
}
.ImagePageItem
{
border: 1px solid black;
width: 100%;
text-align: center;
padding-top: 5px;
margin: 5px 5px 5px
5px;
font-weight: bold;
}
.ImagePageGroup
{
width: 30%;
float: left;
margin: 2px;
padding: 2px;
}
.ImagePageMainLayout
{
padding: 2px;
width: 500px;
}
</style>
<SharePoint:SPDataSource runat="server"
ID="dsProducts"
DataSourceMode="List"
SelectCommand="<Query><OrderBy><FieldRef
Name='ID'/></OrderBy></Query>">
<SelectParameters>
<asp:Parameter Name="ListName"
DefaultValue="Products"
/>
</SelectParameters>
</SharePoint:SPDataSource>
<table width="520px" cellpadding="0" cellspacing="0">
<tr>
<td align="center">
<asp:ListView
ID="listViewProducts"
GroupItemCount="3"
runat="server" GroupPlaceholderID="GroupsGoHere"
ItemPlaceholderID="ItemsGoHere"
Orientation="Horizontal"
DataSourceID="dsProducts">
<LayoutTemplate>
<div runat="server"
id="Main" class="ImagePageMainLayout">
<div runat="server"
id="GroupsGoHere">
</div>
</div>
</LayoutTemplate>
<GroupTemplate>
<div runat="server"
id="Images" class="ImagePageGroup">
<div runat="server"
id="ItemsGoHere">
</div>
</div>
</GroupTemplate>
<ItemTemplate>
<div id="Item"
align="center" runat="server" class="ImagePageItem" style="width:
100%">
<table
cellpadding="0"
cellspacing="0"
width="100%">
<tr>
<td>
<asp:Image
ID="imgProduct" runat="server" AlternateText='<%# Eval("Title")%>' Height="100"
Width="100" ImageUrl='<%# Eval("Product Image")%>' />
</td>
</tr>
<tr>
<td>
<asp:Label
ID="lblProduct" runat="server" Text='<%# Eval("Title")%>'>
</asp:Label>
</td>
</tr>
<tr>
<td>
रु <asp:Label ID="lblProductCost" runat="server" Font-Size="15px" Text='<%#
Eval("Cost")%>'>
</asp:Label>
</td>
</tr>
</table>
</div>
</ItemTemplate>
<ItemSeparatorTemplate>
<%--
<br />--%>
</ItemSeparatorTemplate>
<EmptyDataTemplate>
No Products found.
</EmptyDataTemplate>
</asp:ListView>
</td>
</tr>
<tr>
<td align="center">
<asp:DataPager ID="ImagesDataPager"
runat="server"
PageSize="10"
PagedControlID="listViewProducts">
<Fields>
<asp:NextPreviousPagerField
ButtonType="Link"
ShowFirstPageButton="false"
ShowPreviousPageButton="true"
ShowNextPageButton="False"
PreviousPageText="<<
Previous" RenderDisabledButtonsAsLabels="false" />
<asp:NumericPagerField
/>
<asp:NextPreviousPagerField
ButtonType="Link"
ShowLastPageButton="false"
ShowNextPageButton="true"
ShowPreviousPageButton="False"
FirstPageText="Previous"
NextPageText="Next >>"
RenderDisabledButtonsAsLabels="false"
/>
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
|
Output:
C. ListView control with ObjectDataSource
Here I created custom ObjectDataSource as a data source for ListView control.
Steps:
1.
First I created two SharePoint lists
Books and BookAuthors. Books
list contains a look up column to BookAuthors list.
BookAuthors list:
Books list:
2.
Then I created a custom class BookShop
which provides combined data from above two lists. I used Linq to SharePoint provider
to fetch the data from SharePoint.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Runtime.InteropServices;
using Microsoft.SharePoint.Security;
using System.Security.Permissions;
namespace ASP.NETControlsInSharePoint
{
[Guid("fb6ec799-882c-4815-a6f0-3ecb95f711f9")]
[SharePointPermissionAttribute(SecurityAction.InheritanceDemand,
ObjectModel = true)]
[SharePointPermissionAttribute(SecurityAction.LinkDemand,
ObjectModel = true)]
public class
BookShop
{
public List<BooksInformation> GetBooksByAuthorId(string
authorId)
{
using (SharepointCustomDevelopmentDataContext
dtContext = new SharepointCustomDevelopmentDataContext(SPContext.Current.Web.Url))
{
//To improve performance during readonly operations
dtContext.ObjectTrackingEnabled = false;
var results = from
book in dtContext.Books
where book.AuthorName.Id.ToString() == authorId
select new BooksInformation
{
BookId
= (int)book.Id ,
BookName = book.Title,
AuthorName = book.AuthorName.Title,
AuthorAlias = book.AuthorName.AuthorAlias != null
? book.AuthorName.AuthorAlias : "",
BookCost = book.BookCost.ToString()
};
return results.ToList();
}
}
}
public class
BooksInformation
{
public int BookId
{ get; set;
}
public string
BookName { get; set;
}
public string
AuthorName { get; set;
}
public string
AuthorAlias { get; set;
}
public string
BookCost { get; set;
}
}
}
|
3.
After that I created a dropdown list and populated it with Book Authors using
SPDataSource.
<SharePoint:SPDataSource runat="server"
ID="dsBookAuthors"
DataSourceMode="List"
SelectCommand="<Query><OrderBy><FieldRef
Name='Title'/></OrderBy></Query>">
<SelectParameters>
<asp:Parameter Name="ListName"
DefaultValue="BookAuthors"
/>
</SelectParameters>
</SharePoint:SPDataSource>
<asp:DropDownList
runat="server"
ID="ddlAuthorTitles"
DataSourceID="dsBookAuthors"
DataTextField="Title"
DataValueField="ID"
AutoPostBack="true">
</asp:DropDownList>
|
4.
Then I created
ObjectDataSource which points to GetBooksByAuthorId
method of BookShop class. Note that
it passes dropdown value as parameter to GetBooksByAuthorId
method.
<asp:ObjectDataSource
ID="dsBookShop"
runat="server"
SelectMethod="GetBooksByAuthorId"
TypeName="ASP.NETControlsInSharePoint.BookShop,ASP.NETControlsInSharePoint,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=67027cb88f6143d4">
<SelectParameters>
<asp:ControlParameter
ControlID="ddlAuthorTitles"
Name="authorId"
PropertyName="SelectedValue"
Type="String"
/>
</SelectParameters>
</asp:ObjectDataSource>
|
5.
Then I created ListView control pointing to the ObjectDataSource created above.
<asp:ListView
ID="listView"
runat="server"
DataSourceID="dsBookShop">
<LayoutTemplate>
<table
class="TableCSS"
cellpadding="0"
cellspacing="0"
width="100%">
<tr class="TableHeader">
<td align="center">
Book Id
</td>
<td>
Book Name
</td>
<td>
Author Name
</td>
<td>
Book Cost
</td>
</tr>
<tr id="ItemPlaceholder"
runat="server">
</tr>
<tr>
<td colspan="4"
class="dataPager">
<asp:DataPager ID="DataPager1"
runat="server"
PageSize="5">
<Fields>
<asp:NextPreviousPagerField
ButtonType="Link"
ShowFirstPageButton="false"
ShowPreviousPageButton="true"
ShowNextPageButton="False"
PreviousPageText="<<
Previous" RenderDisabledButtonsAsLabels="false" />
<asp:NumericPagerField
/>
<asp:NextPreviousPagerField ButtonType="Link" ShowLastPageButton="false" ShowNextPageButton="true"
ShowPreviousPageButton="False"
FirstPageText="Previous"
NextPageText="Next >>"
RenderDisabledButtonsAsLabels="false"
/>
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr class="noramlRowData">
<td align="center">
<asp:Label
ID="Label1" runat="server" Text='<%# Eval("BookId")%>'>
</asp:Label>
</td>
<td>
<asp:Label
ID="Label2" runat="server" Text='<%# Eval("BookName")%>'>
</asp:Label>
</td>
<td>
<asp:Label
ID="Label4" runat="server" Text='<%#FormatAuthorName(Eval("AuthorName"),
Eval("AuthorAlias")) %>'>
</asp:Label>
</td>
<td>
रु <asp:Label ID="Label3" runat="server" Text='<%# Eval("BookCost")%>'>
</asp:Label>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr class="alternatingRowData">
<td align="center">
<asp:Label
ID="Label1" runat="server" Text='<%# Eval("BookId")%>'>
</asp:Label>
</td>
<td>
<asp:Label
ID="Label2" runat="server" Text='<%# Eval("BookName")%>'>
</asp:Label>
</td>
<td>
<asp:Label
ID="Label4" runat="server" Text='<%#FormatAuthorName(Eval("AuthorName"),
Eval("AuthorAlias")) %>'>
</asp:Label>
</td>
<td>
रु <asp:Label ID="Label3" runat="server" Text='<%# Eval("BookCost")%>'>
</asp:Label>
</td>
</tr>
</AlternatingItemTemplate>
<EmptyDataTemplate>
<table
cellpadding="0"
cellspacing="0"
width="100%"
class="TableCSS">
<tr class="TableHeader">
<td align="center">
Book Id
</td>
<td>
Book Name
</td>
<td>
Author Name
</td>
<td>
Book Cost
</td>
</tr>
<tr class="noramlRowData">
<td colspan="4"
align="center">
No Books found. He is not a writer.
</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:ListView>
|
Output:
In addition, below are the two steps we need to do to make
ListView control and ObjectDataSource
work in Visual web part.
1.
By default, Visual web part does not support asp.net 3.5 controls. To enable
them, you will need to add following registration line in the user control (.ascx)
<%@ Register Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI.WebControls" TagPrefix="asp"
%>
|
2.
ObjectDataSource TypeName property
As by default, assemblies in SharePoint are stored in GAC, fully qualified name
of the custom class needs to be mentioned while binding it to the ObjectDataSource in
TypeName property. For BIN deployment
this is not true. However, as a good practice, I suggest to mention fully qualified
name even in case of BIN deployment. E.g.
<asp:ObjectDataSource
ID="dsBookShop"
runat="server"
SelectMethod="GetBooksByAuthorId"
TypeName="ASP.NETControlsInSharePoint.BookShop,ASP.NETControlsInSharePoint,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=67027cb88f6143d4"/>
|
Note that similar to the every SharePoint control, SPDataSource control does not work in
SandBox solutions.
For the reference, I have uploaded the source code here. It also contain List Templates of the lists I used. Hope this proves a good read!
Updated (7/7/2012):
Updating this post so that visitors would also get to know
about SharePoint Designer capabilities of integrating asp.net controls in
SharePoint. Matthew Bramer has written a series of posts on this.
Even though posts are for MOSS 2007, they still apply to
SharePoint 2010.
|
For the reference, I have uploaded the source code here. It also contain List Templates of the lists I used. Hope this proves a good read!
I've written something similar using SPD instead. I'd love for you to check it out and offer your comments:
ReplyDeletehttp://mattbramer.blogspot.com/2010/09/sharepoint-integrate-aspnet-controls.html
Hi Matthew,
DeleteI already went through your blog 2 days back. Good read! I've updated my post...have a look.