Thursday, August 7, 2008

Create custom ListViewWebPart

Hi All,

First of All Special Thanks to

Arun

Creating ListViewWebpart programmatically

http://www.sharepointu.com/forums/p/2141/5876.aspx

Guzel

http://forums.msdn.microsoft.com/en-US/sharepointdevelopment/thread/e7eda00c-14c7-41f9-87b1-09d911c30378/


Basics can be found @ :
http://www.sharepointplatform.com/teamblog/Lists/Posts/Post.aspx?List=427bfca2%2Db731%2D4c19%2D87c6%2D83c90460e02c&ID=42

These sites and people have helped us in this venture.
We are great full to all those on the internet, who apply their thoughts and provide with such good codes and tips.
We sincerely apologize if we forgot to mention any one over here.



Now to the venture: Custom ListViewWebPart

Recently one of the projects in which we are involved needed to develop a Web Part.
This Web Part had to look same as the OOTB (Out Of The Box) DataView.

The requirment further stated that it should have the Following:

1) Show Data from any List.
2) Show Data from any View applied on the List.
3) Show Data from any List with Dynamic Queries.
4) Show be able to sort,filter,edit,add new item etc on the List.

:) There was a never ending List of requirments that the client gave us.


We Created this Web Part from the Base
Microsoft.SharePoint.WebPartPages.ListViewWebPart

he Parameter that Make it Fully Dynamic are in the
Tool Panel --> Miscellaneous

Below are the Images that will give you the exact Picture:








The Source Code of the entire Web Part is here:


using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Security.Principal;




namespace Com.SharePointKings.Webparts.Com.SharePointKings.Webparts
{


[Guid("5BAC68E6-0B8C-4b0b-85B7-7D8340480D5C")]
public class CustomListViewWebPart : System.Web.UI.WebControls.WebParts.WebPart
{
#region Variable Declaration
private string strlisttolink = string.Empty;
private string strViewOfSourceList = string.Empty;
private string strQuery = string.Empty;

#endregion
#region Properties

//Get and Set Property of the Source List
[Personalizable(true),
WebBrowsable(),
WebDisplayName("List Name"),
WebDescription("Pass the Name of the List")]
//Get and Set Property of the Source List
public string ListToLink
{
get
{
return strlisttolink;
}
set
{
strlisttolink = value;
}
}

[Personalizable(true),
WebBrowsable(),
WebDisplayName("View"),
WebDescription("Pass Name of the View that you will like to apply to the List")]
//Get and Set Property of the Source List
public string ViewOfSourceList
{
get
{
return strViewOfSourceList;
}
set
{
strViewOfSourceList = value;
}
}
[Personalizable(true),
WebBrowsable(),
WebDisplayName("Query"),
WebDescription("Pass the Filter Query")]
//Get and Set Property of the Source List
public string FilterQuery
{
get
{
return strQuery;
}
set
{
strQuery = value;
}
}

#endregion

public CustomListViewWebPart()
{
this.ExportMode = WebPartExportMode.All;
}



protected override void CreateChildControls()
{
base.CreateChildControls();

try
{

SPWeb web = SPContext.Current.Web;
SPList list = web.Lists[ListToLink];



ViewToolBar toolbar = new ViewToolBar();

SPContext context = SPContext.GetContext(this.Context, list.Views[ViewOfSourceList].ID, list.ID, SPContext.Current.Web);

toolbar.RenderContext = context;

Controls.Add(toolbar);




// Instantiate the web part
ListViewWebPart lvwp = new ListViewWebPart();
lvwp.ListName = list.ID.ToString("B").ToUpper();
lvwp.ViewGuid = list.Views[ViewOfSourceList].
ID.ToString("B").ToUpper();

SPView webPartView = web.Lists[ListToLink].Views[ViewOfSourceList];
SPList objList = web.Lists[ListToLink];
webPartView.Query = FilterQuery;

// Remove the Toolbar!
// First Option: Do it throught OOTB.This needs to be done from the VIEW of the Web Part
// Second Option: Do it trhough Coding.This line is required to ensure that all the appropriate internal nodes of the SPView are populated

String temp = webPartView.SchemaXml;
System.Reflection.PropertyInfo ViewProp = lvwp.GetType().GetProperty("View", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
SPView spView = ViewProp.GetValue(lvwp, null) as SPView;
// This forces a refresh of the views internal xml or the node's cild nodes are not populated


PropertyInfo nodeProp = webPartView.GetType().GetProperty("Node", BindingFlags.NonPublic | BindingFlags.Instance);
XmlNode node = nodeProp.GetValue(webPartView, null) as XmlNode;

// Now get the Toolbar node from the view so we can update its type property
XmlNode toolbarNode = node.SelectSingleNode("Toolbar");
if (toolbarNode != null)
{
toolbarNode.Attributes["Type"].Value = "None";
web.AllowUnsafeUpdates = true;
webPartView.Update();
web.AllowUnsafeUpdates = false;
}
//End Remove the Toolbar!

web.AllowUnsafeUpdates = true;
webPartView.Update();
objList.Update();
web.AllowUnsafeUpdates = false;
lvwp.GetDesignTimeHtml();
this.Controls.Add(lvwp);
}
catch (Exception ex)
{
Label lbl = new Label();
lbl.Text = "Error occured: ";
lbl.Text += ex.Message;
this.Controls.Add(lbl);
}
}


protected override void Render(HtmlTextWriter writer)
{
EnsureChildControls();
base.Render(writer);
}
}
}

45 comments:

Ryan Nash said...

I've almost got this up and running, however there is a part in the code that says "//remove the toolbar!" yet there is no code underneath it actually removing the toolbar.

How did you remove the toolbar? I tried setting the webPartView.Toolbar property to "None" or "" but it didn't work, I can't really even see where the webPartView is tied to the lvwp.

Manoj Iyer said...

Hi Ryan,

Yes we tried to remove the ToolBar the same way as you did, but it didn't work. So we remove the code.

Now there is another way you can get rid of the Extra ToolBar that you see.

Go to the List in Question. When you do an Edit Page and Click on "Modify Shared Web Part" on the Default All Items Page of the List.

In the List View ToolPane on the Right Hand Side, Select the View that you are going to give as the Property for our WebPart, select "No ToolBar" in the ToolBar Type: Property.

This will Remove the ToolBar.

No go to the Page where you have your CustomListViewWebPart. Just refresh the Page.

This will get you rid of the ToolBar.

I hope we have answered your query. Thanks a Lot for your supprot.

-SharepointKings

Manoj Iyer said...

Hi Rayn,

In reply to your query of Removing the Toolbar! we have something for you. This chunk of code with do it smoothly.


// Remove the Toolbar!
// First Option: Do it throught OOTB.This needs to be done from the VIEW of the Web Part
// Second Option: Do it trhough Coding.This line is required to ensure that all the appropriate internal nodes of the SPView are populated

String temp = webPartView.SchemaXml;
System.Reflection.PropertyInfo ViewProp = lvwp.GetType().GetProperty("View", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
SPView spView = ViewProp.GetValue(lvwp, null) as SPView;
// This forces a refresh of the views internal xml or the node's cild nodes are not populated


PropertyInfo nodeProp = webPartView.GetType().GetProperty("Node", BindingFlags.NonPublic | BindingFlags.Instance);
XmlNode node = nodeProp.GetValue(webPartView, null) as XmlNode;

// Now get the Toolbar node from the view so we can update its type property
XmlNode toolbarNode = node.SelectSingleNode("Toolbar");
if (toolbarNode != null)
{
toolbarNode.Attributes["Type"].Value = "None";
web.AllowUnsafeUpdates = true;
webPartView.Update();
web.AllowUnsafeUpdates = false;
}
//End Remove the Toolbar!


Rayn, We appreciate your curiosity and are looking forward for more Queries

Anonymous said...

It can be easy done by using ListView/ListViewByQuery/ViewToolbar controls from Microsoft.SharePoint.WebControls without reflection.

Chris Buchanan said...

There's another post detailing how to change the toolbar types between Standard, FreeForm and None located at http://spschris.blogspot.com. Check it out.

Chris Buchanan
Solution Developer
www.redsphere.ca

David said...

Hi all!

I´m trying to develope a webpart like this. But, my first doubt. is it possible to develop de LisViewWebPart for list from other sites or subsites? Even other site collection, this is my customer´s requirements. Thanks in advance and nice post!

Parth Patel said...

Hi Devid,

good requirement, we had not tried with different site collection, subsite or other site but if you can check the code then list view webpart is bind with list and its view. so it should work theoritically. We will try if we get time to work on this requirement.

And if you tried then please share your experience weather its working or not.

dirq said...

Thank you for the code. It's a big help so far. I have the same requirements as David - I need to pull data from a list in the parent web site. I've switched the list to use the parent list but I've been getting an error that originates in the lvwp.GetDesignTimeHtml() call. It's rather lengthy so I'll just give you the basics:

List does not exist. The page you selected contains a list that does not exist. It may have been deleted by another user.It seems that the internal call to "EnsureData(0)" is not able to find the list. The internals of EnsureData is obfuscated so I can't look at the code in Reflector.

Any ideas? Has anyone created a list view of items from another site? I need the rendered web part to look like the standard lists.

Thanks a lot for your help,

Dirk Watkins

Mark Stokes said...

Awesome. At last a post that works post Infrastructure Updates.

I have created my own post based on this here:

http://sharepointstudio.com/People/MarkStokes/Lists/Posts/Post.aspx?ID=27

Anonymous said...

When using a query, the query works! However, when you use the toolbar actions to export to spreadsheet, it displays all items instead of the filtered items. Is there a way to get the export to only export the filtered items?

SharePoint Kings said...

Mark,

Nice effort, Thanks for sharing we will check it and revert soon.

SharePoint Kings said...

To Anonymous,

its basic behavior of list view, and out of the box web part is also behaving the same. so this is expected behavior

Todde said...

I've almost got this up but its not running. Is the code wrong. What is my failure.

SharePoint Kings said...

Todd,
what's the error?
where are you stuck?

Mado said...

The key to getting the ListViewWebpart to work for lists on a different level:

Set the WebId property of the ListViewWebpart to the web.ID the list is on.

Anonymous said...

Hi,

Excellent code...How to get different views from subsites and other site collections.How to do that?

SharePoint Kings said...

sorry for subsite thing,
still not done that.

Unknown said...

Hi folks,

thanks a lot for the useful code. I have a question: even if I choose the "Project Tasks" view of a Projects list I created, and I link it to the custom Web part via its miscellaneous properties, I cannot manage to have the Gantt chart to appear: I just get the normal tabular list of the tasks. Any ideas?

Many thanks

Lorenzo

SharePoint Kings said...

gus, no idea about programmatically

for gant chart we have to use SPListTemplateType.GanttTasks somewhere

nice thing to investigate, will try to get back to you soon.

Unknown said...

Hi,

I have two ListViewwebpart on same page. If I drill down to any folder of one webpart the other webpart shows the content of rootfolder. For an example in First webpart I drill to Level 1 folder and then i thought drill down in second webpart. The page gets post back and first webpart displays the contents of rootfolder and not the Lvel1 folder.

Any idea on this behavior of Listwebpart.

Please mail me on divyesh.kotadia@bsil.com.

Thanks,
Divyesh

SharePoint Kings said...

divyesh,

yes able to get same behavior, as you are getting.

don't know about this behavior.
need to research on that.
will try to get back to you soon.

Thanks for sharing.

Anonymous said...

Hi

This is good information but I somehow see that connections are disabled for it. How can I ensure its connections are enabled to be able to connect to other webparts or I connect between two instances of the same custom listviewwebpart with different datasources

SharePoint Kings said...

@Anonymous,

just check there should be some property and you have override few method to enable connection.

we had not explored but check how you create simple custom webpart with connection same way it should have some provision but frankly we still had to explore this thing.

Chris said...

Hi there,
got some problem with this code.
Adding the compiled webpart to a webpartpage works fine but there are no entrys visible. Only the toolbar is displayed. I doublechecked the name of the list and the view is correct.
Any ideas?

Chris

SharePoint Kings said...

chris,

you can debug the code and while debugging check whether you are getting correct list and view as well as correct XML.

Unknown said...

Hi, is this working in Sharepoint 2010 ?

Thanks,
San

SharePoint Kings said...

san,
we had not tried in 2010 yet...:(

Laur said...

Hi, I got this up and running, I made some changes, removed the dynamic parts, and added some of my own code, but I noticed a problem, with both the original code and my modified one, in order to acces the page the webparts is placed on it need to have the "design" permision ... is there a way to use this without giving every user the design permision ?

SharePoint Kings said...

it was not working because we are modifying and updating web part. this permission is not available below designer user so you might face this thing.

you can try SPSecurity.RunWithElevatedPrivileges so code with run under admin. so it should work

actually we had not faced this problem though or we might not notice that :)

thanks for sharing.

Anonymous said...

I find that when I set the toolbar settings to off, it effects the original List View, not a Copy of the View.

Can't have people doing that in my system.

Im about to try this, Regexing my RenderContents

StringWriter sw = new StringWriter();
Html32TextWriter tw = new Html32TextWriter(sw);

EnsureChildControls();
RenderChildren(tw);

//Do Regex Here,

writer.Write(sw.ToString());



I know it'll work as I've done this in the past way way back in 2003, not nice but doesnt change stuff.

Anonymous said...

You've almost got it here just noticed one thing that turned me away from there.

When you associate this web part to a list, the code seems to do something that messes with the configuration of the library. For example, a custom Ribbon button I created would all of a sudden not show any more!

SharePoint Kings said...

@Anonymous,
This has been written for SharePoint 2007 where no ribbon control was introduced.

Mark Stokes said...

Sorry for anyone who has tried to access my blog at the link I posted a couple of years ago.

Here is the current (and hopefully permanent) link to the post:

http://www.sharepointstudio.com/Blog/Lists/Posts/Post.aspx?ID=3

Mark Stokes said...

Hi,

The link in my previous post is now incorrect.

My old post on this can be found here:

http://www.sharepointstudio.com/Blog/Lists/Posts/Post.aspx?ID=3

Mark Stokes

Monsur Ahmed said...

I was trying to run the code in SharePoint 2010. I am seeing the toolbar but no data is displayed. Even while I was debugging I found lvwp.GetDesignTimeHtml(); was returning correct data, but in the page its a webpart with toolbar only, but no data os displayed. Please help

SharePoint Kings said...

@Monsur Ahmed,
we had not tried this code in 2010, but as you said if GetDesignTimeHtml is showing proper data then it should show proper data.

try to use code in your oninit event of your webpart. this may resolve this problem.

Monsur Ahmed said...

Hi All,

This code is working on SharePoint 2010. All you need to do is comment the line
lvwp.GetDesignTimeHtml();

If you dont commnet this line then you will be able to see only the webpart on the page but no data will be displayed. I dont know why this is happenning...anybody has any idea..

Thanks anyway to everybody who has contributed to this post..its really a cool post and its helped me a lot..

SharePoint Kings said...

@Monsur Ahmed,

Thanks a lot for sharing your experience, this will help a lot for everyone who stuck in custom listviewwebpart in SP2010.

we will surely try the solution you suggest and try to update the existing article for SP2010.

Thanks again for you effort and sharing.

Jessica said...

Thanks, great work. This worked great for me. However, I also need the same connection functionality as in the OOTB web part. Specifically, to be able to filter by a field based on a selected row (by clicking the radio button). I have done quite a bit of research and haven't been able to get this to work. I tried making this web part a provider using IWebPartField, however, when I attempt to connect to an OOTB web part, the option isn't available. I am able to connect to another custom list view web part, however, not sure how to get the radio buttons to display. Has anyone done this before or can point me in the right direction. Or is it possible to get this to work as a provider to an OOTB web part? I'm sure I'd still need to figure out how to add radio buttons. Thanks for any assistance. I'm a relatively new SharePoint developer.

pdanan said...

Hi,
Thanks for Sharepoint Kings
and Monsur Ahmed for this running in SP2010

SharePoint Kings said...

@Jessica, you can connect your custom listview to SharePoint OOTB webpart.

we are not sure what exactly you are missing as we had did this quite a long time back.

still if you share some more information (sample or so) then it would be great.

Elie said...

Hi,
Thanks a lot for this post.

I want to know if it's possible to connect a new ListViewWebPart() to a infopath form with his preview like a classic listview ?

Indeed, I need to update my list with 2 or 3 filters on the same column and then display the InfoPath form in his edition mode

thank you in advance

SharePoint Kings said...

Hi Elie,
we did not understand how list-view will connect to infopath which looks like classic list-view?


can you please explain in detail?

Niyaz said...

Hi Manoj

Thanks for this worderful post. Almost it worked for me but struck at Query part. I have a list where need to group by multiple columns. Could you please guide how do I pass the query to this webpart?

Many Thanks

Anonymous said...

i have used this in sharepoint 2010 it is working fine but for users having read access is not working properly, giving error message access denied.




Share your SharePoint Experiences with us...
As good as the SharePointKings is, we want to make it even better. One of our most valuable sources of input for our Blog Posts comes from ever enthusiastic Visitors/Readers. We welcome every Visitor/Reader to contribute their experiences with SharePoint. It may be in the form of a code stub, snippet, any tips and trick or any crazy thing you have tried with SharePoint.
Send your Articles to sharepointkings@gmail.com with your Profile Summary. We will Post them. The idea is to act as a bridge between you Readers!!!

If anyone would like to have their advertisement posted on this blog, please send us the requirement details to sharepointkings@gmail.com