<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ton Stegeman [MVP] weblog</title>
	<atom:link href="http://vspug.com/tonstegeman/feed/" rel="self" type="application/rss+xml" />
	<link>http://vspug.com/tonstegeman</link>
	<description>Just another VSPUG - Virtual SharePoint User Group weblog</description>
	<lastBuildDate>Sun, 13 Jan 2008 15:32:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>MOSS 2007 Filter webparts part 3 &#8211; Adding and connecting SharePoint filter webparts in code and a the page layout</title>
		<link>http://vspug.com/tonstegeman/2008/01/13/moss-2007-filter-webparts-part-3-adding-and-connecting-sharepoint-filter-webparts-in-code-and-a-the-page-layout/</link>
		<comments>http://vspug.com/tonstegeman/2008/01/13/moss-2007-filter-webparts-part-3-adding-and-connecting-sharepoint-filter-webparts-in-code-and-a-the-page-layout/#comments</comments>
		<pubDate>Sun, 13 Jan 2008 15:32:09 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[On my weblog on tonstegeman.com, I just published the 3rd article in the series on SharePoint filter webparts. It shows you can add filter providers and consumers to SharePoint pages through code. It also shows how to connect the 2 and how to configure the connection.
The last part of the article shows how you can [...]]]></description>
			<content:encoded><![CDATA[<p>On my weblog on tonstegeman.com, I just published the 3rd article in the series on SharePoint filter webparts. It shows you can add filter providers and consumers to SharePoint pages through code. It also shows how to connect the 2 and how to configure the connection.</p>
<p>The last part of the article shows how you can add and connect the same webparts directly in a page layout.</p>
<p>You can find it <a href="http://www.tonstegeman.com/Blog/Lists/Posts/Post.aspx?ID=52">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2008/01/13/moss-2007-filter-webparts-part-3-adding-and-connecting-sharepoint-filter-webparts-in-code-and-a-the-page-layout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Querying SharePoint for content &#8211; using SPSiteDataQuery and CrossListQueryInfo</title>
		<link>http://vspug.com/tonstegeman/2007/11/10/querying-sharepoint-for-content-using-spsitedataquery-and-crosslistqueryinfo/</link>
		<comments>http://vspug.com/tonstegeman/2007/11/10/querying-sharepoint-for-content-using-spsitedataquery-and-crosslistqueryinfo/#comments</comments>
		<pubDate>Sat, 10 Nov 2007 13:31:51 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[On my new weblog, I just posted a new article on querying sharepoint sites using the SPSiteDataQuery objects and the CrossListQueryInfo objects. I have also described some of the issues that I ran into while writing the Content By Type webpart.
]]></description>
			<content:encoded><![CDATA[<p>On my new weblog, I just posted <a href="http://www.tonstegeman.com/Blog/Lists/Posts/Post.aspx?ID=47">a new article</a> on querying sharepoint sites using the SPSiteDataQuery objects and the CrossListQueryInfo objects. I have also described some of the issues that I ran into while writing the Content By Type webpart.</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/11/10/querying-sharepoint-for-content-using-spsitedataquery-and-crosslistqueryinfo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving my weblog to SharePoint</title>
		<link>http://vspug.com/tonstegeman/2007/11/06/moving-my-weblog-to-sharepoint/</link>
		<comments>http://vspug.com/tonstegeman/2007/11/06/moving-my-weblog-to-sharepoint/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 21:46:17 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[At the moment I am busy moving my weblog to a SharePoint weblog. Most articles are already available on the new weblog. You can find my new weblog on this url. I will post links to the new articles on this blog, but it might be better to update your reader settings. If you are [...]]]></description>
			<content:encoded><![CDATA[<p>At the moment I am busy moving my weblog to a SharePoint weblog. Most articles are already available on the new weblog. You can find my new weblog on <a href="http://www.tonstegeman.com/blog">this url</a>. I will post links to the new articles on this blog, but it might be better to update your reader settings. If you are using my feedburner url (http://feeds.feedburner.com/tonstegeman<a href="http://www.feedburner.com/fb/a/dashboard?id=1081999">)</a>&nbsp;you should be fine, because that is updated to the new url.</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/11/06/moving-my-weblog-to-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing the Content By Type webpart</title>
		<link>http://vspug.com/tonstegeman/2007/10/11/introducing-the-content-by-type-webpart/</link>
		<comments>http://vspug.com/tonstegeman/2007/10/11/introducing-the-content-by-type-webpart/#comments</comments>
		<pubDate>Thu, 11 Oct 2007 21:36:07 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[Update 07&#8211;11&#8211;2007: The beta period is now closed. I will continue to work on the feedback of users who are currently testing the webpart. On my new weblog I will post the updates and the 1.0 release in the coming weeks.
I have been working on a new web part that aggregates content of a specific [...]]]></description>
			<content:encoded><![CDATA[<p>Update 07&ndash;11&ndash;2007: The beta period is now closed. I will continue to work on the feedback of users who are currently testing the webpart. On <a href="http://www.tonstegeman.com/blog">my new weblog </a>I will post the updates and the 1.0 release in the coming weeks.</p>
<p>I have been working on a new web part that aggregates content of a specific content type into a gridview. Much like the Content Query web part, but easier to use by end-users. They just need to select the content type and the columns they want to be displayed (that&rsquo;s why I called it &ldquo;Content by Type&rdquo;).</p>
<p>The most important features are: </p>
<p>&ndash; Works in WSS and MOSS<br />&ndash; Casting / formatting of column data types<br />&ndash; Links to items and its context in contextmenu<br />&ndash; Links to lookup / person fields<br />&ndash; Filter items using MOSS filter web parts<br />&ndash; Supports grouping/sorting and paging</p>
<p><a href="http://www.xs4all.nl/~tonstgmn/blog/image001.png"><img alt="Image001" src="http://www.xs4all.nl/~tonstgmn/blog/image001_thumb.jpg" border="0" /></a></p>
<p>The screenshot above shows the Content By Type webpart in action. The view displays 4 columns of this content type. The view is grouped by content type and sorted by Modified date. When configuring the webpart, users simply choose a content type and the web part lets them pick the columns they want. The screenshot below shows part of the configuration. Users can (un)select the available content type fields and configure the links for these fields. After configuring the other web part properties (scope, grouping, sorting, list type, etc.) the web part will query for items that match the selected content type(s) and display the results in a grid.<br /><img alt="Image003" src="http://www.xs4all.nl/~tonstgmn/blog/image003.png" border="0" /></p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/10/11/introducing-the-content-by-type-webpart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Export user information to Excel using &quot;Export to spreadsheet&quot; in SharePoint 2007</title>
		<link>http://vspug.com/tonstegeman/2007/10/03/export-user-information-to-excel-using-quot-export-to-spreadsheet-quot-in-sharepoint-2007/</link>
		<comments>http://vspug.com/tonstegeman/2007/10/03/export-user-information-to-excel-using-quot-export-to-spreadsheet-quot-in-sharepoint-2007/#comments</comments>
		<pubDate>Wed, 03 Oct 2007 19:00:21 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[In mosts lists in SharePoint the Actions menu has an option &#8220;Export to spreadsheet&#8221;. Using this option you can easily export the contents of the current view to an Excel spreadsheet.I got the question why this link is not available in the User Information list. This is the list that you can access from &#8220;People [...]]]></description>
			<content:encoded><![CDATA[<p>In mosts lists in SharePoint the Actions menu has an option &ldquo;Export to spreadsheet&rdquo;. Using this option you can easily export the contents of the current view to an Excel spreadsheet.I got the question why this link is not available in the User Information list. This is the list that you can access from &ldquo;People and Groups&rdquo; &ndash; &ldquo;All People&rdquo;.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Userinfo1" src="http://www.xs4all.nl/~tonstgmn/blog/userinfo1.png" border="0" /></p>
<p>The&nbsp; Actions menu on this page does not have the option &ldquo;Export to spreadsheet&rdquo;. You can still export the content of this list by using the url below:</p>
<p><a href="http://[SITEURL]/_vti_bin/owssvr.dll?CS=109&amp;Using=_layouts/query.iqy&amp;List=[LISTID]&amp;View=[VIEWID]&amp;CacheControl=1"><font face="Courier New" size="2">http://<strong>[SITEURL]</strong>/_vti_bin/owssvr.dll?CS=109&amp;Using=_layouts/query.iqy&amp;List=<strong>[LISTID]</strong>&amp;View=<strong>[VIEWID]</strong>&amp;CacheControl=1</font></a></p>
<p>In this url, you will need to change these 3 options:</p>
<ul>
<li>[SITEURL] &ndash; the url of your top level site</li>
<li>[LISTID] &ndash; The Guid of the User Information List</li>
<li>[VIEWID] &ndash; The Guid of the view that you want to export.</li>
</ul>
<p>The easiest way to get the [LISTID] and [VIEWID] is to select &ldquo;List Settings&rdquo; in the &ldquo;Settings&rdquo; menu from the screenshot above. First you need to configure&nbsp;a view to have the columns and filters etc. to get the users that you want to export. This is exactly the same process as in any other SharePoint list. While you are configuring your view, the address bar of your browser contains the IDs that you will need:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Userinfo2" src="http://www.xs4all.nl/~tonstgmn/blog/userinfo2.png" border="0" /></p>
<p>Copy the <strong>List </strong>and <strong>View</strong> querystring parameters&nbsp;from this url to the url mentioned above. </p>
<p>Then copy the full url with all correct values in your browser address bar, and the user information will show up in Excel:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Userinfo3" src="http://www.xs4all.nl/~tonstgmn/blog/userinfo3.png" border="0" /></p>
<p>In my case the full url looks like this:</p>
<p><a href="http://office2007/_vti_bin/owssvr.dll?CS=109&amp;Using=_layouts/query.iqy&amp;List=%7B299130F0%2D2E0B%2D4A02%2D8AF0%2D43BA54C79B28%7D&amp;View=%7B45A446EB%2DCFA4%2D4DEE%2D8616%2D5B43AFBC7B31%7D&amp;CacheControl=1">http://<strong>office2007</strong>/_vti_bin/owssvr.dll?CS=109&amp;Using=_layouts/query.iqy&amp;List=<strong>%7B299130F0%2D2E0B%2D4A02%2D8AF0%2D43BA54C79B28%7D</strong>&amp;View=<strong>%7B45A446EB%2DCFA4%2D4DEE%2D8616%2D5B43AFBC7B31%7D</strong>&amp;CacheControl=1</a></p>
<p>At this point I thought, I might as well create a feature that add this action as an item to the Actions menu for the list. So I created a feature file and an elements file and added a &ldquo;CustomAction&rdquo; element. I set the RegistrationType to List and the RegistrationId to 112, which is the list&nbsp;template type id for this list. After registering and activating the feature, my new menu item did not show up in the actions menu. It looks like this list looks like a normal SharePoint list, but it is not 100%. Although the first screenshot shows an Actions and Settings menu, these items seem not to be created as in all the other lists. If you go to the List Settings of the list, select one of the views and click OK, you will see this screenshot:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Userinfo4" src="http://www.xs4all.nl/~tonstgmn/blog/userinfo4.png" border="0" /></p>
<p>It looks like the normal Toolbar was removed from the list schema and the menus are added in another way. The difference is that in the screenshot above, we are in the page&nbsp;<font face="Courier New" size="2">/_catalogs/users/simple.aspx</font> and in the first screenshot we are on page <font face="Courier New" size="2">/_layouts/people.aspx</font>. This people.aspx page contains the menu items for our actions menu. Because it is not recommended to change the SharePoint pages directly, I gave up trying to add my item to the Actions menu. </p>
<p>Instead I created an item in the site settings page. In the &ldquo;Users and Permissions&rdquo; sections users now have an opion &ldquo;Export User Information&rdquo;:</p>
<p>&nbsp;&nbsp; <img alt="Userinfo5" src="http://www.xs4all.nl/~tonstgmn/blog/userinfo5.png" border="0" /></p>
<p>The XML file for my feature:</p>
<div class="cf">
<pre class="cl"><span class="cb1">&lt;</span><span class="cb2">Feature</span><span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp; </span><span class="cb3">xmlns</span><span class="cb1">=</span>&quot;<span class="cb1">http://schemas.microsoft.com/sharepoint/</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp; </span><span class="cb3">Id</span><span class="cb1">=</span>&quot;<span class="cb1">E9189036-3847-4D63-8A13-483FDAE44973</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp; </span><span class="cb3">Title</span><span class="cb1">=</span>&quot;<span class="cb1">Export User Information to spreadsheet</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp; </span><span class="cb3">Description</span><span class="cb1">=</span>&quot;<span class="cb1">Menu item to export user information to a spreadsheet.</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp; </span><span class="cb3">Scope</span><span class="cb1">=</span>&quot;<span class="cb1">Site</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;</span><span class="cb2">ElementManifests</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &lt;</span><span class="cb2">ElementManifest</span><span class="cb1"> </span><span class="cb3">Location</span><span class="cb1">=</span>&quot;<span class="cb1">elements.xml</span>&quot;<span class="cb1"> /&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;/</span><span class="cb2">ElementManifests</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&lt;/</span><span class="cb2">Feature</span><span class="cb1">&gt;</span></pre>
</div>
<p>And the XML file for the elements.xml file: Please note that you will need to replace [LISTID] and [VIEWID] with the appropriate values (see above)</p>
<div class="cf">
<pre class="cl"><span class="cb1">&lt;?</span><span class="cb2">xml</span><span class="cb1"> </span><span class="cb3">version</span><span class="cb1">=</span>&quot;<span class="cb1">1.0</span>&quot;<span class="cb1"> </span><span class="cb3">encoding</span><span class="cb1">=</span>&quot;<span class="cb1">utf-8</span>&quot;<span class="cb1"> ?&gt;</span></pre>
<pre class="cl"><span class="cb1">&lt;</span><span class="cb2">Elements</span><span class="cb1"> </span><span class="cb3">xmlns</span><span class="cb1">=</span>&quot;<span class="cb1">http://schemas.microsoft.com/sharepoint/</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;</span><span class="cb2">CustomAction</span><span class="cb1"> </span><span class="cb3">Id</span><span class="cb1">=</span>&quot;<span class="cb1">ADD173BC-C9B2-48EE-A1AF-3529C2338C06</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &nbsp; </span><span class="cb3">GroupId</span><span class="cb1">=</span>&quot;<span class="cb1">UsersAndPermissions</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &nbsp; </span><span class="cb3">Location</span><span class="cb1">=</span>&quot;<span class="cb1">Microsoft.SharePoint.SiteSettings</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &nbsp; </span><span class="cb3">Sequence</span><span class="cb1">=</span>&quot;<span class="cb1">100</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">Title</span><span class="cb1">=</span>&quot;<span class="cb1">Export User Information</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &nbsp; </span><span class="cb3">Description</span><span class="cb1">=</span>&quot;<span class="cb1">Export User Information to spreadsheet.</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &lt;</span><span class="cb2">UrlAction</span><span class="cb1"> </span><span class="cb3">Url</span><span class="cb1">=</span>&quot;<span class="cb1">/_vti_bin/owssvr.dll?CS=109</span><span class="cb3">&amp;amp;</span><span class="cb1">Using=_layouts/query.iqy</span><span class="cb3">&amp;amp;</span><span class="cb1">List=[LISTID]</span><span class="cb3">&amp;amp;</span><span class="cb1">View=[VIEWID]</span><span class="cb3">&amp;amp;</span><span class="cb1">CacheControl=1</span>&quot;<span class="cb1">/&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;/</span><span class="cb2">CustomAction</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&lt;/</span><span class="cb2">Elements</span><span class="cb1">&gt;</span></pre>
</div>
<p>After installing and activating the feature at the site collection features, the menu option is available.</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/10/03/export-user-information-to-excel-using-quot-export-to-spreadsheet-quot-in-sharepoint-2007/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Localizing SharePoint 2007 site columns using resource files.</title>
		<link>http://vspug.com/tonstegeman/2007/09/27/localizing-sharepoint-2007-site-columns-using-resource-files/</link>
		<comments>http://vspug.com/tonstegeman/2007/09/27/localizing-sharepoint-2007-site-columns-using-resource-files/#comments</comments>
		<pubDate>Thu, 27 Sep 2007 21:40:17 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[The site columns that are deployed by SharePoint are localized out of the box. In a Dutch SharePoint site, the displayname of field &#8220;Date Picture Taken&#8221; is &#8220;Afbeelding gemaakt op&#8221;. In this post I will show you how to do this for your own . The XML definition for the displayname of this&#160;field (from the [...]]]></description>
			<content:encoded><![CDATA[<p>The site columns that are deployed by SharePoint are localized out of the box. In a Dutch SharePoint site, the displayname of field &ldquo;Date Picture Taken&rdquo; is &ldquo;Afbeelding gemaakt op&rdquo;. In this post I will show you how to do this for your own . The XML definition for the displayname of this&nbsp;field (from the fields feature looks like this:</p>
<div class="cf">
<pre class="cl"><span class="cb1">DisplayName</span><span class="cb2">=</span>&quot;<span class="cb2">$Resources:core,Date_Picture_Taken;</span>&quot;</pre>
</div>
<p>This string is a reference to the resource files. These files can be found in folder 12HIVEResources. The part of the string in the example after &ldquo;$Resources&rdquo; references the resource file. In this case, this is &ldquo;core&rdquo;. If we take a look in the resources folder, we see there are 3 resource files:</p>
<ul>
<li>core.resx</li>
<li>core.en-US.resx</li>
<li>core.nl-nl.resx</li>
</ul>
<p>In our Dutch site, the resource strings are loaded from &ldquo;core.nl-nl.resx&rdquo;. In the name of this file, &ldquo;nl-nl&rdquo; is the language locale. Please note however that SharePoint does not load all resources from this location at runtime.&nbsp;Resources&nbsp;used in ASPX pages&nbsp;are loaded from the App_GlobalResources folder under your inetpub folder (see <a href="http://www.graphicalwonder.com/?p=522">this item</a> by Shane Perran and this item by <a href="http://www.mikhaildikov.com/2007/03/sharepoint-resources-types-use-and_2163.html">Mikhail Dikov</a>). In most cases this folder is &ldquo;C:InetpubwwwrootwssVirtualDirectories80App_GlobalResources&rdquo;. In case of the site columns created in&nbsp;a feature, the resources are loaded from the Resources folder in the 12HIVE.</p>
<p>We can use exact the same mechanism for our own site columns (this is not limited to site columns, but I am using this as an example). Here are the steps:</p>
<ul>
<li>Create a resource file called &ldquo;tst.resx&rdquo;</li>
<li>Add these 2 items:
<div class="cf">
<pre class="cl"><span class="cb1">&nbsp; &lt;</span><span class="cb2">data</span><span class="cb1"> </span><span class="cb3">name</span><span class="cb1">=</span>&quot;<span class="cb1">MyColumns</span>&quot;<span class="cb1"> </span><span class="cb3">xml:space</span><span class="cb1">=</span>&quot;<span class="cb1">preserve</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &lt;</span><span class="cb2">value</span><span class="cb1">&gt;</span><strong><font color="#ff0000">My custom fields</font></strong><span class="cb1">&lt;/</span><span class="cb2">value</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;/</span><span class="cb2">data</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;</span><span class="cb2">data</span><span class="cb1"> </span><span class="cb3">name</span><span class="cb1">=</span>&quot;<span class="cb1">TST_RegionField</span>&quot;<span class="cb1"> </span><span class="cb3">xml:space</span><span class="cb1">=</span>&quot;<span class="cb1">preserve</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &lt;</span><span class="cb2">value</span><span class="cb1">&gt;</span><strong><font color="#ff0000">Region field description</font></strong><span class="cb1">&lt;/</span><span class="cb2">value</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;/</span><span class="cb2">data</span><span class="cb1">&gt;</span></pre>
</div>
</li>
<li>Create a resource file called &ldquo;tst.nl-nl.resx&rdquo;</li>
<li>Add these 2 items:
<div class="cf">
<pre class="cl"><span class="cb1">&nbsp; &lt;</span><span class="cb2">data</span><span class="cb1"> </span><span class="cb3">name</span><span class="cb1">=</span>&quot;<span class="cb1"><strong><font color="#009f00">MyColumns</font></strong></span>&quot;<span class="cb1"> </span><span class="cb3">xml:space</span><span class="cb1">=</span>&quot;<span class="cb1">preserve</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &lt;</span><span class="cb2">value</span><span class="cb1">&gt;</span><strong><font color="#ff0000">Mijn gedefinieerde kolommen</font></strong><span class="cb1">&lt;/</span><span class="cb2">value</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;/</span><span class="cb2">data</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;</span><span class="cb2">data</span><span class="cb1"> </span><span class="cb3">name</span><span class="cb1">=</span>&quot;<span class="cb1"><font color="#009f00"><strong>TST_RegionField</strong></font></span>&quot;<span class="cb1"> </span><span class="cb3">xml:space</span><span class="cb1">=</span>&quot;<span class="cb1">preserve</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; &lt;</span><span class="cb2">value</span><span class="cb1">&gt;</span><strong><font color="#ff0000">Beschrijving regio veld</font></strong><span class="cb1">&lt;/</span><span class="cb2">value</span><span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;/</span><span class="cb2">data</span><span class="cb1">&gt;</span></pre>
</div>
</li>
<li>Copy the 2 resx files to the Resources folder in the 12 folder:<br />&ldquo;C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12Resources&rdquo;</li>
<li>Create a new feature that add a new site column in the ElementManifest file:
<div class="cf">
<pre class="cl"><span class="cb1">&lt;?</span><span class="cb2">xml</span><span class="cb1"> </span><span class="cb3">version</span><span class="cb1">=</span>&quot;<span class="cb1">1.0</span>&quot;<span class="cb1"> </span><span class="cb3">encoding</span><span class="cb1">=</span>&quot;<span class="cb1">utf-8</span>&quot;<span class="cb1">?&gt;</span></pre>
<pre class="cl"><span class="cb1">&lt;</span><span class="cb2">Elements</span><span class="cb1"> </span><span class="cb3">xmlns</span><span class="cb1">=</span>&quot;<span class="cb1">http://schemas.microsoft.com/sharepoint/</span>&quot;<span class="cb1">&gt;</span></pre>
<pre class="cl"><span class="cb1">&nbsp; &lt;</span><span class="cb2">Field</span><span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">ID</span><span class="cb1">=</span>&quot;<span class="cb1">{373AC34A-AD29-48CF-8E20-D352CACC602D}</span>&quot;<span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">Type</span><span class="cb1">=</span>&quot;<span class="cb1">Note</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">Name</span><span class="cb1">=</span>&quot;<span class="cb1">emfRegionField</span>&quot;<span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">StaticName</span><span class="cb1">=</span>&quot;<span class="cb1">emfRegionField</span>&quot;<span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">Group</span><span class="cb1">=</span>&quot;<span class="cb1">$Resources:tst,<font color="#009f00"><strong>MyColumns</strong></font>;</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">DisplayName</span><span class="cb1">=</span>&quot;<span class="cb1">$Resources:tst,<font color="#009f00"><strong>TST_RegionField</strong></font>;</span>&quot;</pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">Required</span><span class="cb1">=</span>&quot;<span class="cb1">FALSE</span>&quot;<span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">NumLines</span><span class="cb1">=</span>&quot;<span class="cb1">25</span>&quot;<span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">RichText</span><span class="cb1">=</span>&quot;<span class="cb1">FALSE</span>&quot;<span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">Sortable</span><span class="cb1">=</span>&quot;<span class="cb1">FALSE</span>&quot;<span class="cb1"> </span></pre>
<pre class="cl"><span class="cb1">&nbsp;&nbsp;&nbsp; </span><span class="cb3">RowOrdinal</span><span class="cb1">=</span>&quot;<span class="cb1">0</span>&quot;<span class="cb1">/&gt;</span></pre>
<pre class="cl"><span class="cb1">&lt;/</span><span class="cb2">Elements</span><span class="cb1">&gt;</span></pre>
</div>
</li>
<li>According to the naming we have used in the first steps, our resource strings now have to be defined like this:</li>
<ul>
<li><strong><em>$Resources:</em></strong> &ndash; identify as resource string</li>
<li><em><strong>tst,</strong></em> &ndash; the filename prefix of the resx file</li>
<li><strong><em>TST_RegionField;</em></strong> &ndash; identifier for the string</li>
</ul>
<li>Please note that only the displayname and the groupname&nbsp;are localized. The staticname and internal name are equal for all languages.</li>
<li>Deploy and activate the feature</li>
<li>IISRESET</li>
<li>In an English site my site columns now look like this:<br />&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Localize1" src="http://www.xs4all.nl/~tonstgmn/blog/localize1.png" border="0" /></li>
<li>And the same screenshot from a Dutch site:<br />&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Localize2" src="http://www.xs4all.nl/~tonstgmn/blog/localize2.png" border="0" /></li>
</ul>
<p>Creation and deployment of site columns through features is not covered in this post. There are several good articles out there that can help you with this. One of them is <a href="/tonstegeman/archive/2006/06/30/badding-site-columns-to-office-sharepoint-server-by-using-features.aspx">my own</a>, to get you started.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/09/27/localizing-sharepoint-2007-site-columns-using-resource-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MOSS 2007 Filter webparts part 2 &#8211; providing and consuming a default value and using Excel Services</title>
		<link>http://vspug.com/tonstegeman/2007/09/22/moss-2007-filter-webparts-part-2-providing-and-consuming-a-default-value-and-using-excel-services/</link>
		<comments>http://vspug.com/tonstegeman/2007/09/22/moss-2007-filter-webparts-part-2-providing-and-consuming-a-default-value-and-using-excel-services/#comments</comments>
		<pubDate>Sat, 22 Sep 2007 09:56:14 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[In this post I described a custom filter provider and consumer webpart for Microsoft Office SharePoint Server 2007. In this post I show how you can make the provider send a default value to other filter webparts. The second step is to show how you can make a webpart accept an incoming default value from [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="/tonstegeman/archive/2007/09/21/moss-2007-filter-webparts-part-1-create-your-own-provider-and-consumer.aspx">this post</a> I described a custom filter provider and consumer webpart for Microsoft Office SharePoint Server 2007. In this post I show how you can make the provider send a default value to other filter webparts. The second step is to show how you can make a webpart accept an incoming default value from another filter webpart. At the end of this post I will give an example of how you can use your filter provider in combination with Excel Services.</p>
<p><strong>Step 1 &ndash; Provide a default value</strong></p>
<p>We will change the behaviour of our provider webpart so that it is able to send filter values and a default value to other webparts. Please note that a default value is always single valued. For a webpart that supports multiple values, multiple default values seem not to be supported by the framework. The first thing to do is implement the IDefaultFilterValue interface:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">FilterProvider</span> :</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.Web.UI.WebControls.WebParts.<span class="cb2">WebPart</span>,</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">ITransformableFilterValues</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">IDefaultFilterValue</span></pre>
</div>
<p>In the implementation the value of the first selected checkbox is sent to the consumer of the default value. This is just the first selected value, because the framework only support single valued default values:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">string</span> DefaultValue</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">for</span> (<span class="cb1">int</span> i = 0; i &lt; _regions.Items.Count; i++)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (_regions.Items<img src="/emoticons/emotion-55.gif" alt="Idea" />.Selected)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> _regions.Items<img src="/emoticons/emotion-55.gif" alt="Idea" />.Value;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> <span class="cb1">null</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>The last thing to do is notify the WebPartManager that we now support default values:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; [<span class="cb1">ConnectionProvider</span>(</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;Default region&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;UniqueIDForRegionDefault&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; AllowsMultipleConnections = <span class="cb3">true</span>)]</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb3">public</span> <span class="cb1">IDefaultFilterValue</span> SetDefaultValueConnection()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">return</span> <span class="cb3">this</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>As described in the previous post, the ConnectionProvider attribute has 3 parameter. The first in de snippet above is the displayname. This shows up when you connect your provider to another filter webpart:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters7" src="http://www.xs4all.nl/~tonstgmn/blog/filters7.png" border="0" /></p>
<p><strong>Step 2 &ndash; Test the default value provider</strong></p>
<p>The easiest way to test your filter provider is to use the Text Filter WebPart as the consumer. Add both webparts to the page and send the &ldquo;Default region&rdquo; to the text filter webpart. After selecting a value you webparts will look like this:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters8" src="http://www.xs4all.nl/~tonstgmn/blog/filters8.png" border="0" /></p>
<p><strong>Step 3 &ndash; Consume default values</strong></p>
<p>In this step we will change the provider webpart to make it support incoming default values. It will support multiple connections, so that we can setup multiple webparts on our page that can pass a default value to our webpart. Because we support multiple incoming default values, we setup a private member that will hold our connections:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">List</span>&lt;<span class="cb2">IDefaultFilterValue</span>&gt; _defaultValues;</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">List</span>&lt;<span class="cb2">IDefaultFilterValue</span>&gt; DefaultValues</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> _defaultValues; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> FilterProvider()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _defaultValues = <span class="cb1">new</span> <span class="cb2">List</span>&lt;<span class="cb2">IDefaultFilterValue</span>&gt;();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>The only other thing to do is to notify the WebPartManager that we now support incoming default values.</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; [<span class="cb1">ConnectionConsumer</span>(</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;default region&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;UniqueIDForRegionDefaultConsumer&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; AllowsMultipleConnections = <span class="cb3">true</span>)]</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb3">public</span> <span class="cb3">void</span> SetFilter(<span class="cb1">IDefaultFilterValue</span> defaultFilterValue)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">if</span> (defaultFilterValue != <span class="cb3">null</span>)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DefaultValues.Add(defaultFilterValue);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>Again, this attribute takes 3 parameter, where the displayname is used in setting up the connection when initiated from the consuming webpart:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters11" src="http://www.xs4all.nl/~tonstgmn/blog/filters11.png" border="0" /></p>
<p>In the OnPreRender of our provider webpart, we need to handle the incoming default values:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> <span class="cb1">override</span> <span class="cb1">void</span> OnPreRender(<span class="cb2">EventArgs</span> e)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">foreach</span> (<span class="cb2">IDefaultFilterValue</span> defaultValue <span class="cb1">in</span> DefaultValues)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (!<span class="cb1">string</span>.IsNullOrEmpty(defaultValue.DefaultValue))</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">foreach</span> (<span class="cb2">ListItem</span> region <span class="cb1">in</span> _regions.Items)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (<span class="cb1">string</span>.Compare(region.Value, defaultValue.DefaultValue, <span class="cb1">true</span>) == 0)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; region.Selected = <span class="cb1">true</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">base</span>.OnPreRender(e);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>&nbsp;</p>
<p><strong>Step 4 &ndash; Test the default value consumer</strong></p>
<p>To test the we add the provider webpart to the page and also a Current User Filter webpart. The current user filter webpart reads the value of one of the profile properties and passes that as the default value to our region selector. By managing the profile property for our users, users now automatically have their default region selected when they hit the page.</p>
<p>The Current User Filter webpart is a context filter webpart and therefore is not visible at runtime. When the page is in edit mode, it looks like this:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters10" src="http://www.xs4all.nl/~tonstgmn/blog/filters10.png" border="0" /></p>
<p>In this screenshot you see 3 webpart:</p>
<ul>
<li>Current user filter &ndash; reads the value from my user profile</li>
<li>FilterProvider &ndash; gets the default value from the first webpart and passes its value as the default value to the text filter webpart</li>
<li>Default region &ndash; text filter webpart that gets a default value from the FilterProvider.</li>
</ul>
<p>Of course this testscenario is not very useful, but it shows that you can use MOSS filter webparts to build pages that make it easy for users to select the content they wish to see. By using default values it makes it even easier. I have used the &ldquo;Office&rdquo; property of my profile to set the default value for the users:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters9" src="http://www.xs4all.nl/~tonstgmn/blog/filters9.png" border="0" /></p>
<p>The screenshot below shows that our default value consumer supports multiple default values. By using this mechanism, we can set multiple default values in our webpart, but just 1 for each incoming connection. This page has 2 text filter webparts that both send their value as the default value to our FilterProvider webpart:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters12" src="http://www.xs4all.nl/~tonstgmn/blog/filters12.png" border="0" /></p>
<p><strong>Step 5 &ndash; Test our provider with Excel Services</strong></p>
<p>Filter webparts can also be used to send input to Excel sheets rendered in an Excel Web Access webpart. In the screenshot below you see our provider webpart that sends the selected values to a parameter in the Excel sheet. This Excel sheet shows a pivot table the gets it data from the Analysis Services demo cube Adventureworks. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters15" src="http://www.xs4all.nl/~tonstgmn/blog/filters15.png" border="0" /></p>
<p>The Excel Web Access webpart supports&nbsp;3 types of connections. I used the connection type &ldquo;Get Filter Values From&rdquo;. When configuring the connection in the second step (see screenshot below), you can select the named parameters in the sheet. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters14" src="http://www.xs4all.nl/~tonstgmn/blog/filters14.png" border="0" /></p>
<p>You can name these parameters when you publish the Excel sheet. When I published my report, I created a parameter called &ldquo;Geo&rdquo;:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters16" src="http://www.xs4all.nl/~tonstgmn/blog/filters16.png" border="0" /></p>
<p>The only thing I changed to the provider are the available options. Because we now are sending values to Excel Services that connects to Analysis Services, we need to send MDX instead of plain text. My provider is now setup like this. The exact syntax of the MDX of course depends on the dimensions in the cube.</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> <span class="cb1">override</span> <span class="cb1">void</span> CreateChildControls()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">base</span>.CreateChildControls();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions = <span class="cb1">new</span> <span class="cb2">CheckBoxList</span>();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;Australia&quot;</span>, <span class="cb3">&quot;[Geography].[Geography].[Country].&amp;[Australia]&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;Canada&quot;</span>, <span class="cb3">&quot;[Geography].[Geography].[Country].&amp;[Canada]&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;France&quot;</span>, <span class="cb3">&quot;[Geography].[Geography].[Country].&amp;[France]&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;Germany&quot;</span>, <span class="cb3">&quot;[Geography].[Geography].[Country].&amp;[Germany]&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;United Kingdom&quot;</span>, <span class="cb3">&quot;[Geography].[Geography].[Country].&amp;[United Kingdom]&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.AutoPostBack = <span class="cb1">true</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">this</span>.Controls.Add(_regions);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>By using Excel combined with&nbsp;the out of the box SharePoint filter web parts and your own, you have very flexible, powerful reporting mechanism.</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/09/22/moss-2007-filter-webparts-part-2-providing-and-consuming-a-default-value-and-using-excel-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MOSS 2007 Filter webparts part 1 &#8211; create your own provider and consumer</title>
		<link>http://vspug.com/tonstegeman/2007/09/21/moss-2007-filter-webparts-part-1-create-your-own-provider-and-consumer/</link>
		<comments>http://vspug.com/tonstegeman/2007/09/21/moss-2007-filter-webparts-part-1-create-your-own-provider-and-consumer/#comments</comments>
		<pubDate>Fri, 21 Sep 2007 21:14:41 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[Microsoft Office SharePoint Server 2007 offers a number of filter webparts. These can be used to gather filtering options from a number of different sources. The filter value(s) selected by the users&#160;can be sent to other SharePoint webparts. This connection is supported through the normal webpart connections. The webpart that sends the filter values is [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft Office SharePoint Server 2007 offers a number of filter webparts. These can be used to gather filtering options from a number of different sources. The filter value(s) selected by the users&nbsp;can be sent to other SharePoint webparts. This connection is supported through the normal webpart connections. The webpart that sends the filter values is called the <strong><em>provider</em></strong>. The webpart that receives and handles the values is called the <strong><em>consumer</em></strong>. Providers can normally send values to filter the consumer or to set the default value for the consumer. Examples of filter providers are:</p>
<ul>
<li>Business Data Catalog Filter</li>
<li>Choice Filter</li>
<li>Current User Filter</li>
<li>SharePoint List Filter</li>
</ul>
<p>Examples of filter consumers are:</p>
<ul>
<li>SharePoint ListView WebPart</li>
<li>Excel Web Access</li>
</ul>
<p>In this post I will show you how you can write your own provider and consumer.</p>
<p><strong>Step 1 &ndash;&nbsp;Create&nbsp;the provider webpart</strong></p>
<p>Our provider webpart is a very simple webpart that just show 4 checkboxes with 4 regions. When the user selects&nbsp;the checkboxes, the selected values are sent to the connected consumers.&nbsp;It exposes just 1 parameter called &ldquo;Region&rdquo;.&nbsp;When added to the page, our provider looks like this (page is in edit mode):</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters1" src="http://www.xs4all.nl/~tonstgmn/blog/filters1.png" border="0" /></p>
<p>The first thing to do is create a new webpart that implements the ITransformableFilterValues interface (from the Microsoft.SharePoint.WebPartPages namespace):</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">FilterProvider</span> :</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.Web.UI.WebControls.WebParts.<span class="cb2">WebPart</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">ITransformableFilterValues</span> </pre>
</div>
<p>We add a private member to our class for the CheckBoxList and setup the control in CreateChildControls:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">CheckBoxList</span> _regions;</pre>
</div>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> <span class="cb1">override</span> <span class="cb1">void</span> CreateChildControls()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">base</span>.CreateChildControls();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions = <span class="cb1">new</span> <span class="cb2">CheckBoxList</span>();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;North&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;South&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;West&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.Items.Add(<span class="cb1">new</span> <span class="cb2">ListItem</span>(<span class="cb3">&quot;East&quot;</span>));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _regions.AutoPostBack = <span class="cb1">true</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">this</span>.Controls.Add(_regions);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>&nbsp;</p>
<p>To implement the interface, we add these properties/methods:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">bool</span> AllowEmptyValue</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> <span class="cb1">false</span>; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">bool</span> AllowAllValue</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> <span class="cb1">true</span>; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">bool</span> AllowMultipleValues</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> <span class="cb1">true</span>; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">string</span> ParameterName</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> <span class="cb2">&quot;Region&quot;</span>; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb3">ReadOnlyCollection</span>&lt;<span class="cb1">string</span>&gt; ParameterValues</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; EnsureChildControls();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">List</span>&lt;<span class="cb1">string</span>&gt; regions = <span class="cb1">new</span> <span class="cb3">List</span>&lt;<span class="cb1">string</span>&gt;();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">for</span> (<span class="cb1">int</span> i = 0; i &lt; _regions.Items.Count; i++)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (_regions.Items<img src="/emoticons/emotion-55.gif" alt="Idea" />.Selected)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; regions.Add(_regions.Items<img src="/emoticons/emotion-55.gif" alt="Idea" />.Value);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">ReadOnlyCollection</span>&lt;<span class="cb1">string</span>&gt; result = <span class="cb1">new</span> <span class="cb3">ReadOnlyCollection</span>&lt;<span class="cb1">string</span>&gt;(regions);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> result;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>Our webpart does not support empty values (we don&rsquo;t send values if nothing is selected). Our webpart supports&nbsp;the &ldquo;All&rdquo; value . The first two properties therefore return false. Because we have 4 checkboxes, we do support multiple values and therefore AllowMultipleValues returns true. These properties are important when the connection to the consumer is made. These options either show or hide connection parameters. The property ParameterName returns the name of the parameter that is used when the provider is connected to the consumer:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters2" src="http://www.xs4all.nl/~tonstgmn/blog/filters2.png" border="0" /></p>
<p>In our case this is &ldquo;Region&rdquo;. The last property ParameterValues returns the selected values as a readonly collection of strings. The last thing to do is create a new method in our webpart&nbsp;with the &ldquo;ConnectionProvider&rdquo; attribute. This makes the WebPartManager expose the connection to available consumers.</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; [<span class="cb1">ConnectionProvider</span>(</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;Region&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;UniqueIDForRegionConnection&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; AllowsMultipleConnections = <span class="cb3">true</span>)]</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb3">public</span> <span class="cb1">ITransformableFilterValues</span> SetConnection()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">return</span> <span class="cb3">this</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>This attribute takes (in the overload I used) three parameters: </p>
<ul>
<li>The displayname. This is the name that you will see when setting up the connection:<br />&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters3" src="http://www.xs4all.nl/~tonstgmn/blog/filters3.png" border="0" /><br />I have set this to &ldquo;Region&rdquo;, as you can see in the screenshot above.</li>
<li>ID &ndash; a unique id for the provider connection point</li>
<li>Named Parameters &ndash; this allows you to set AllowsMultipleConnections. My providers can provider its values to multiple consumers, so I have set this to true.</li>
</ul>
<p><strong>Step 2 &ndash; Test the provider</strong></p>
<p>After compiling the assembly and deploying the webpart, we are ready to test the provider. I have created a new document library called &ldquo;MyDocs&rdquo; and added a new multivalued Choice field called &ldquo;DocumentRegion&rdquo;. After that I added a ListView webpart and configured it to show the DocumentRegion field. After connection the 2 webparts, selecting one of the checkboxes will filter the list of documents:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters4" src="http://www.xs4all.nl/~tonstgmn/blog/filters4.png" border="0" /></p>
<p><strong><font color="#ff0000">Warning</font></strong>:&nbsp;although our provider supports and sends multiple values, the list view webpart seems not to handle this correctly.</p>
<p><strong>Step&nbsp;3 &ndash; Create the consumer webpart</strong></p>
<p>Our provider is now ready to send filters to consumers and we will now create our own provider. This again is a very simple webpart that does nothing but render all values for incoming filters. Again we start to create a new webpart:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">FilterConsumer</span> :</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.Web.UI.WebControls.WebParts.<span class="cb2">WebPart</span></pre>
</div>
<p>We create a private member to hold the incoming filter values (IFilterValues from the&nbsp;Microsoft.SharePoint.WebPartPages namespace). We also add a property for the and initialize it in the constructor:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">List</span>&lt;<span class="cb2">IFilterValues</span>&gt; _filterProviders;</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">List</span>&lt;<span class="cb2">IFilterValues</span>&gt; FilterProviders</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> _filterProviders; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> FilterConsumer()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _filterProviders = <span class="cb1">new</span> <span class="cb2">List</span>&lt;<span class="cb2">IFilterValues</span>&gt;();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>&nbsp;In this example I do not handle the incoming filters in a specific way, but just render the incoming values in the Render method:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> <span class="cb1">override</span> <span class="cb1">void</span> Render(System.Web.UI.<span class="cb2">HtmlTextWriter</span> writer)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">foreach</span> (<span class="cb2">IFilterValues</span> filter <span class="cb1">in</span> FilterProviders)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.WriteLine(<span class="cb1">string</span>.Format(<span class="cb3">&quot;Parameter: {0} &lt;br&gt;&quot;</span>, filter.ParameterName));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (filter.ParameterValues != <span class="cb1">null</span>)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">foreach</span> (<span class="cb1">string</span> value <span class="cb1">in</span> filter.ParameterValues)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (!<span class="cb1">string</span>.IsNullOrEmpty(value))</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.WriteLine(<span class="cb1">string</span>.Format(<span class="cb3">&quot;&nbsp; value: {0} &lt;br&gt;&quot;</span>, value));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">base</span>.Render(writer);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>The last thing to do to get the consumer working is add a method to configure the connection. We need to add the ConnectionConsumer attribute (System.Web.UI.WebControls.WebParts namespace). This attribute takes the same 3 parameters:</p>
<ul>
<li>displayname &ndash; I set this to &ldquo;filter&rdquo;. This displayname is used to configure the connection when we initiate the connection from the consumer instead of the provider webpart:<br />&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters5" src="http://www.xs4all.nl/~tonstgmn/blog/filters5.png" border="0" /></li>
<li>id &ndash; a unique name&nbsp;assigned to the consumer connection point.&nbsp;</li>
<li>Named parameter &ndash;&nbsp;In case our webpart needs to support multiple incoming connections, we pass true for the AllowsMultipleConnections parameter.&nbsp;</li>
</ul>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; [<span class="cb1">ConnectionConsumer</span>(</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;filter&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;UniqueIDForConsumer&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; AllowsMultipleConnections = <span class="cb3">true</span>)]</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb3">public</span> <span class="cb3">void</span> SetFilter(<span class="cb1">IFilterValues</span> filterValues)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">if</span> (filterValues != <span class="cb3">null</span>)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; EnsureChildControls();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">List</span>&lt;<span class="cb1">ConsumerParameter</span>&gt; parameters = <span class="cb3">new</span> <span class="cb1">List</span>&lt;<span class="cb1">ConsumerParameter</span>&gt;();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; parameters.Add(<span class="cb3">new</span> <span class="cb1">ConsumerParameter</span>(</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;Region&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">ConsumerParameterCapabilities</span>.SupportsMultipleValues | </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">ConsumerParameterCapabilities</span>.SupportsAllValue));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; parameters.Add(<span class="cb3">new</span> <span class="cb1">ConsumerParameter</span>(</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">&quot;Status&quot;</span>, </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">ConsumerParameterCapabilities</span>.SupportsMultipleValues | </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">ConsumerParameterCapabilities</span>.SupportsAllValue));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; filterValues.SetConsumerParameters(</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">new</span> System.Collections.ObjectModel.<span class="cb1">ReadOnlyCollection</span>&lt;<span class="cb1">ConsumerParameter</span>&gt;(parameters));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3">this</span>.FilterProviders.Add(filterValues);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>The SetFilter method above serves 2 purposes. It stored details about the incoming connections and values. It also exposes the parameters the our consumer exposes and the properties of these parameters. Matching combinations of these parameters and the options of the provider webpart allow you to connect the provider and consumer. If these options do not match, the parameter will not show up when configuring the connection.&nbsp;In my example, the consumer webpart exposes 2 parameters; Region and Status. The options used for these parameters (SupportsMultipleValues and SupportsAllValue) allow me to connect to our own provider, to the Choice Filter webpart and the Text Filter provider webpart. A provider webpart that supports the &ldquo;All&rdquo; &ldquo;value for example can never connect to a consumer parameter the does not have the SupportsAllValue option. This parameter simply does not show up in the &ldquo;Configure Connection&rdquo; dialog.</p>
<p><strong>Step 4 &ndash; Test the consumer</strong></p>
<p>To test the consumer, I have added our own provider, a Text Filter webpart and a Choice Filter webpart that supports multiple values&nbsp;to the page. These are all connected&nbsp;to our custom consumer.&nbsp;After selecting values in each of the 3 providers, our consumer looks like this:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Filters6" src="http://www.xs4all.nl/~tonstgmn/blog/filters6.png" border="0" /></p>
<p>Filter webparts are a very flexible, very powerful way to organize content on your pages. In the next post, I will describe how you can use filter&nbsp;providers to pass a default value to other webparts and how you can&nbsp;provide a value to a parameter in an Excel sheet in the EWA webpart. If you are looking for more information, <a href="http://msdn2.microsoft.com/en-us/library/ms494838.aspx">this page</a> is an excellent start:</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/09/21/moss-2007-filter-webparts-part-1-create-your-own-provider-and-consumer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting the associated page layouts from a SharePoint document library</title>
		<link>http://vspug.com/tonstegeman/2007/09/08/getting-the-associated-page-layouts-from-a-sharepoint-document-library/</link>
		<comments>http://vspug.com/tonstegeman/2007/09/08/getting-the-associated-page-layouts-from-a-sharepoint-document-library/#comments</comments>
		<pubDate>Sat, 08 Sep 2007 10:06:19 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[In MOSS 2007 you can associate a page layout with a content type. The MOSS publishing feature uses this mechanism to select the content type for the new page that you create by using the &#8220;Create Page&#8221; option from the Site Actions menu. By selecting a page layout, you directly select the content type for [...]]]></description>
			<content:encoded><![CDATA[<p>In MOSS 2007 you can associate a page layout with a content type. The MOSS publishing feature uses this mechanism to select the content type for the new page that you create by using the &ldquo;Create Page&rdquo; option from the Site Actions menu. By selecting a page layout, you directly select the content type for your content page.</p>
<p>In code I needed to find out what Page Layouts are associated with the content types that are associated with a document library. In this example I created a very simple WinForms application that lists the available page layouts for the content types associate with the &ldquo;Pages&rdquo; library in the &ldquo;News&rdquo; site of a publishing portal. </p>
<p>This document library has these content types associated:</p>
<p>&nbsp;&nbsp;&nbsp; <img alt="Pagelayouts1" src="http://www.xs4all.nl/~tonstgmn/blog/pagelayouts1.png" border="0" /></p>
<p>By navigating to the Master Page gallery, we can find out what page layouts are associated to the &ldquo;Article Page&rdquo; content type:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Pagelayouts2" src="http://www.xs4all.nl/~tonstgmn/blog/pagelayouts2.png" border="0" /></p>
<p>In this case we have 5 page layouts associated to our content type. This is exactly what we want to achieve, but now in code. The first thing to do is get the SPList object for the document library:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">SPSite</span> site = <span class="cb2">new</span> <span class="cb1">SPSite</span>(textBoxWeb.Text);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">SPWeb</span> web = site.OpenWeb();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">SPList</span> list = web.Lists[textBoxLibrary.Text];</pre>
</div>
<p>The namespace Microsoft.SharePoint.Publishing contains a class called &ldquo;PublishingWeb&rdquo;. By using this line of code we can get a reference to the publishing web:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">PublishingWeb</span> publishingWeb = <span class="cb1">PublishingWeb</span>.GetPublishingWeb(web);</pre>
</div>
<p>Now we can iterate through the associated content types and find the page layouts&nbsp;associated to the content type&nbsp;using the GetAvailablePageLayouts method. The thing to remember here first is that &nbsp;the&nbsp;content type associated to the document library is&nbsp;not the content type that we associated to the page layout. When a content type is associated to a list, SharePoint automatically generates a new content type that inherits from the content type we choose and associates that to the list. So instead of trying to find what page layouts&nbsp;using the content type, we need to&nbsp;use the parent&nbsp;of our content type. The output log of our code below demonstrates this. First the code:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">foreach</span> (<span class="cb2">SPContentType</span> contentType <span class="cb1">in</span> list.ContentTypes)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3"><font color="#008000">// Log details of content type</font></span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; textBoxResult.Text += </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">string</span>.Format(<span class="cb4">&quot;Content type: {0}
&quot;</span>, contentType.Name);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; textBoxResult.Text += </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">string</span>.Format(<span class="cb4">&quot;&nbsp;&nbsp;&nbsp; Id=: {0}
&quot;</span>, contentType.Id);</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3"><font color="#008000">// Try to find associated page layouts and log number found</font></span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">PageLayout</span>[] layouts = </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; publishingWeb.GetAvailablePageLayouts(contentType.Id);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; textBoxResult.Text += </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">string</span>.Format(<span class="cb4">&quot;&nbsp;&nbsp;&nbsp; Associated Page layouts: {0}
&quot;</span>, layouts.Length.ToString());</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3"><font color="#008000">// Log details of content type parent</font></span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; textBoxResult.Text += </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">string</span>.Format(<span class="cb4">&quot;&nbsp;&nbsp;&nbsp; Parent=: {0}
&quot;</span>, contentType.Parent.Name);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; textBoxResult.Text += </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">string</span>.Format(<span class="cb4">&quot;&nbsp;&nbsp;&nbsp; ParentId=: {0}
&quot;</span>, contentType.Parent.Id);</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3"><font color="#008000">// Try to find associated page layouts for parent and log number found</font></span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; layouts = publishingWeb.GetAvailablePageLayouts(contentType.Parent.Id);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; textBoxResult.Text += </pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">string</span>.Format(<span class="cb4">&quot;&nbsp;&nbsp;&nbsp; Associated Page layouts: {0}
&quot;</span>, layouts.Length.ToString());</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb3"><font color="#008000">// Log the page layouts</font></span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">foreach</span> (<span class="cb2">PageLayout</span> layout <span class="cb1">in</span> layouts)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; textBoxResult.Text += <span class="cb1">string</span>.Format(<span class="cb4">&quot;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Page layout: {0}
&quot;</span>, layout.Name);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>This results in this output for the Article Page content type:</p>
<p><font face="Courier New" size="1">Content type: Article Page<br />&nbsp;&nbsp;&nbsp; Id=: <strong><font color="#ff0000">0&#215;010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D</font></strong>0075C2CA1B0566054FAB8DFC025454149B<br />&nbsp;&nbsp;&nbsp; Associated Page layouts: 0<br />&nbsp;&nbsp;&nbsp; Parent=: Article Page<br />&nbsp;&nbsp;&nbsp; ParentId=: <font color="#ff0000"><strong>0&#215;010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D</strong></font><br />&nbsp;&nbsp;&nbsp; Associated Page layouts: 5<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page layout: PageFromDocLayout.aspx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page layout: ArticleLeft_copy(1).aspx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page layout: ArticleLeft.aspx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page layout: ArticleRight.aspx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page layout: ArticleLinks.aspx<br /></font></p>
<p>By looking at the Id you can see that a new content type called Article Page is attached to the Pages library and we can find the page layouts by using the Parent.&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/09/08/getting-the-associated-page-layouts-from-a-sharepoint-document-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating custom editor parts for a SharePoint webpart</title>
		<link>http://vspug.com/tonstegeman/2007/08/04/creating-custom-editor-parts-for-a-sharepoint-webpart/</link>
		<comments>http://vspug.com/tonstegeman/2007/08/04/creating-custom-editor-parts-for-a-sharepoint-webpart/#comments</comments>
		<pubDate>Sat, 04 Aug 2007 08:10:00 +0000</pubDate>
		<dc:creator>tonstegeman</dc:creator>
		
		<guid isPermaLink="false"></guid>
		<description><![CDATA[

For one of my SharePoint webparts I created a custom EditorPart to edit the properties of the webpart. I had some issues with this editorpart that caused me a headache.My webpart is an ASP.NET 2.0 webpart (System.Web.UI.WebControls.WebParts) that implements the IWebEditable interface. Here is the code of my webpart:

&#160;&#160;&#160; public class TestEditorPart : System.Web.UI.WebControls.WebParts.WebPart, IWebEditable
&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<table>
<td>
<p>For one of my SharePoint webparts I created a custom EditorPart to edit the properties of the webpart. I had some issues with this editorpart that caused me a headache.My webpart is an ASP.NET 2.0 webpart (System.Web.UI.WebControls.WebParts) that implements the IWebEditable interface. Here is the code of my webpart:</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">TestEditorPart</span> : System.Web.UI.WebControls.WebParts.<span class="cb2">WebPart</span>, <span class="cb2">IWebEditable</span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">string</span> _myMessage;</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span class="cb2">WebBrowsable</span>(<span class="cb1">false</span>)]</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span class="cb2">Personalizable</span>(<span class="cb2">PersonalizationScope</span>.Shared)]</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">string</span> MyMessage</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> _myMessage; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">set</span> { _myMessage = <span class="cb1">value</span>; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> <span class="cb1">override</span> <span class="cb1">void</span> Render(<span class="cb2">HtmlTextWriter</span> writer)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">base</span>.Render(writer);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; writer.WriteLine(<span class="cb1">string</span>.Format(<span class="cb3">&quot;Message: {0}.&quot;</span>, MyMessage));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">EditorPartCollection</span> <span class="cb2">IWebEditable</span>.CreateEditorParts()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">List</span>&lt;<span class="cb2">EditorPart</span>&gt; editors = <span class="cb1">new</span> <span class="cb2">List</span>&lt;<span class="cb2">EditorPart</span>&gt;();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; editors.Add(<span class="cb1">new</span> <span class="cb2">MyEditorPart</span>());</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> <span class="cb1">new</span> <span class="cb2">EditorPartCollection</span>(editors);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">object</span> <span class="cb2">IWebEditable</span>.WebBrowsableObject</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">get</span> { <span class="cb1">return</span> <span class="cb1">this</span>; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>In CreateEditorParts() my custom editorpart is created and returned in a new collection. My editor part is called MyEditorPart. I will not discuss the code in detail, because it is pretty straight forward.</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">MyEditorPart</span> : <span class="cb2">EditorPart</span></pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">TextBox</span> _message;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">protected</span> <span class="cb1">override</span> <span class="cb1">void</span> CreateChildControls()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">base</span>.CreateChildControls();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _message = <span class="cb1">new</span> <span class="cb2">TextBox</span>();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Controls.Add(_message);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">override</span> <span class="cb1">bool</span> ApplyChanges()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; EnsureChildControls();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">TestEditorPart</span> webPart = WebPartToEdit <span class="cb1">as</span> <span class="cb2">TestEditorPart</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (webPart != <span class="cb1">null</span>)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; webPart.MyMessage = _message.Text;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> <span class="cb1">true</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">override</span> <span class="cb1">void</span> SyncChanges()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; EnsureChildControls();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">TestEditorPart</span> webPart = WebPartToEdit <span class="cb1">as</span> <span class="cb2">TestEditorPart</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (webPart != <span class="cb1">null</span>)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; _message.Text = webPart.MyMessage;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>After compiling the assembly, deploying it to my SharePoint 2007 server and registering the webpart, I added the webpart to the page. After clicking the &ldquo;Modify&rdquo;Shared Web Part&rdquo;&rdquo;, the page crashes with message &ldquo;An unexpected error has occurred.&rdquo;:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Editorpart1" src="http://www.xs4all.nl/~tonstgmn/blog/editorpart1.png" border="0" /></p>
<p>After adding a constructor to MyEditorPart and setting an ID for my editor part, this problem is solved.</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> MyEditorPart()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">this</span>.ID = <span class="cb2">&quot;MyEditorPart&quot;</span>;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>While testing the webpart, I used this webpart twice on the same page. I changed the message for the first webpart to &ldquo;Message 1&rdquo;. Then I set the message for the other webpart to a different text and switched back to the properties of the first webpart. Although I have the correct webpart selected (see screenshot below) the textbox in the editor part shows the message of the other webpart. See the screenshot below.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt="Editorpart2" src="http://www.xs4all.nl/~tonstgmn/blog/editorpart2.png" border="0" /></p>
<p>After some serious debugging I found out that the ID of the editor part has to be unique for each instance of your webpart. I changed the constructor of my EditorPart to take the ID of the webpart as a parameter. This solved my problem.</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">public</span> MyEditorPart(<span class="cb1">string</span> webPartID)</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">this</span>.ID = <span class="cb2">&quot;MyEditorPart&quot;</span> + webPartID;</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>In the webpart code I changed&nbsp;CreateEditorParts to pass the ID in the constructor:&nbsp;</p>
<div class="cf">
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">EditorPartCollection</span> <span class="cb1">IWebEditable</span>.CreateEditorParts()</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">List</span>&lt;<span class="cb1">EditorPart</span>&gt; editors = <span class="cb2">new</span> <span class="cb1">List</span>&lt;<span class="cb1">EditorPart</span>&gt;();</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; editors.Add(<span class="cb2">new</span> <span class="cb1">MyEditorPart</span>(<span class="cb2">this</span>.ID));</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">return</span> <span class="cb2">new</span> <span class="cb1">EditorPartCollection</span>(editors);</pre>
<pre class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
</div>
<p>You probably already know this if you develop SharePoint webpart, but I didn&rsquo;t and after nearly getting crazy because my text boxes displayed the wrong values in the editor part, I decided to share it.</p>
<p>&nbsp;</p>
</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://vspug.com/tonstegeman/2007/08/04/creating-custom-editor-parts-for-a-sharepoint-webpart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
