Add to My Yahoo! | Google Reader or Homepage | Add to Windows Live | Add to Windows Live Alerts

Wictor Wilén

SharePoint Specialist / Author / MCT / MCTS / MCP / MSc ranting about SharePoint and other interesting Microsoft technologies

Latest postings

What is new with the CssRegistration control in SharePoint 2010

Posted at 2010-03-04 10:41 by Wictor Wilén in Web Parts , SharePoint 2010 with 0 comments.

The CssRegistration class (in Microsoft.SharePoint.WebControls namespace) is one of the most useful controls in SharePoint 2010. It existed in SharePoint 2007 but was fairly limited then. I thought I should guide you through why it is so useful in SharePoint 2010 and why and when you should use it. I briefly mentioned the CssRegistration control in my previous post on SharePoint 2010 themable CSS files. But first some background.

Why the CssRegistration control?

There are plenty of times when you need to add custom CSS definitions to your SharePoint projects, for instance in pages and Web Parts. There are several methods of adding CSSes to your projects. You could use inline CSS styles - which results in a lot of markup which may slow your page/site down. Another approach is creating a CSS file and include it in your master page - better but the CSS is always loaded.

The third option is to add a link tag and reference your CSS in your Web Part so it's only loaded when needed. But if you have several of these Web Parts on your page you will reference it several times. A common method is to override the RenderContents method or similar and add the CSS link tag there. Not a good option either and can result in multiple CSS registrations.

This is the reason for the CssRegistration. This control registers the CSS files with SharePoint and once it is time to render the page it only renders one link tag for each, even though you might have registered the same CSS file multiple times. It is the CssLink control that is responsible for the actual rendering and this control is normally placed in your master page.

The CssRegistration control existed in SharePoint 2007 and it was somewhat useful in removing duplicate CSS links. The problem is that the CSS files and rules are processed in the order that the links appear and the SharePoint 2007 implementation always rendered the CSS files in alphabetically order.

CssRegistration in SharePoint 2010

The new implementation of the CssRegistration have a number of new features. First of all you can specify the order using the After property. The After property contains the name of the CSS that you want to place the CSS after.

Registering two CSS files like this:

CssRegistration

would yield the following output CSS order on a Team site:

  1. myCss.css
  2. myCss2.css
  3. wiki.css
  4. corev4.css

Adding the After property to the controls like this, so that out myCss2 is rendered after corev4 and myCss after myCss2.

CssRegistration and After

would yield this order:

  1. wiki.css
  2. corev4.css
  3. myCss2.css
  4. myCss.css

Pretty smooth!

Another useful new feature of the CssRegistration is that you can add Conditional-CSS expressions so that you can target the CSS files to different browsers.

CssRegistration and ConditionalExpression

By adding the ConditionalExpression parameter to the control we tell the CssLink to render the Conditional-CSS code as well as the CSS link. The result of the registration above is:

 Conditional Expression

If you are targeting a non Internet Explorer browser you should also set the RevealToNonIE  parameter to true.  The reason is that the syntax is not valid XHTML syntax and the extra parameter will add some extra HTML comments to make it valid XHTML. Read all the details on Wikipedia.

The CssRegistration control also has a parameter called EnableCssTheming that allows your CSS to be themed, which I showed in the previous post.

 

I hope this little CssRegistration tutorial was useful - I think it's one of the great improvements in SharePoint 2010!

Creating custom themable CSS files for SharePoint 2010

Posted at 2010-02-17 02:57 by Wictor Wilén in Web Parts , SharePoint 2010 with 1 comments.

SharePoint 2010 has a completely rebuilt theme engine. Instead of having to modify .inf files, create folders and copy and pasting CSS files and images in the SharePoint root we can now create a theme in PowerPoint and upload it to the server. The default SharePoint CSS files are tagged with comments that tells SharePoint to substitute colors and images with the values from the theme. When you switch theme SharePoint generates a new set of CSS files and images with the result of this substation.

What if you have the need to create a custom CSS for you solution or Web Part? How can you use this theme? It's actually quite easy!

Let's take a look at a sample Visual Web Part that is going to have a custom CSS file.

Create the Visual Web Part

First of all we need to start the new awesome/fantastic/productive new Visual Studio 2010 and create a Visual Web Part Project. Add a simple button to the user control and attach a custom CSS class to it.

Button with custom CSS

Add the CSS

Once we have this button with the CSS class we need to create the CSS file and define the class. This is done by adding the SharePoint "Layouts" Mapped Folder to the Project. This will also add a folder with your project name under the Layouts folder - remove that one. Then add a folder structure like this 1033/Styles/Themable to the Layouts folder.

To the Styles folder you then need to add the CSS file with your class. It should look something like this:

.MyCustomClass {
/* [ReplaceColor(themeColor:"Light2-Lightest")] */ border:solid 1px #d9dde1;
/* [ReplaceColor(themeColor:"Light2")] */ background-color:#f5f6f7;
}

The ReplaceColor tag in the CSS comment will replace the colors in the CSS styles using the named color of the theme. For full reference check out corev4.css in the SharePointRoot.

Then copy this file so it has a duplicate in the Themable CSS folder, your solution should look like this:

The solution!

SharePoint will use the CustomStyle.css in the Styles folder, when no theme is activated, so this is your default CSS. When you activate a theme it will take the CustomStyle.css from the Themable folder and substitute the colors as you wrote in the CSS file. Note that if you already have a theme enabled you have to re-enable it or if you make changes to the CSS you also need to re-enable the theme.

Register the CSS

We have one more thing to do to get this thing going - and that is to tell the Visual Web Part to use this CSS. This is done using the CssRegistration control which we add to the Visual Web Part user control like this:

CssRegistration control

You need to specify the Name attribute, which is the name of your CSS file. The EnableCssTheming attribute is not necessary since the default value is true. If it's set to false the CSS in the Styles folder will always be used. If you leave it out or set it to true and provide no CSS in the Themable folder then your CSS will not be loaded.

Try it out!

Now deploy your Visual Web Part and then add it to a page. Then go to Site Settings and change between themes. Isn't it beautiful!

No theme Bittersweet theme Vantage theme

To get some more details - make sure to get my book once it hits the streets!

Local SharePoint 2010 development on Windows 7 - awesome experience

Posted at 2010-02-14 03:35 by Wictor Wilén in Visual Studio , SQL Server , Windows Vista , Windows 7 , SharePoint 2010 with 2 comments.

I thought I should share my experience on working with SharePoint 2010 development on Windows 7. My previous posts on installing SharePoint 2007 on Vista and Windows 7 are posts that are quite popular. The downside with the “old” SharePoint version is that it was not officially supported to install it on a client machine, but SharePoint 2010 is supported for installation on Windows 7 and Windows Vista SP1 for development purposes.

There are many opinions on having SharePoint 2010 installed on your client OS. Some thinks it is despicable, but I think it is great and I’ve used local installations for years now. It’s perfect for rapid development, testing and demos. In seconds you can spin up a site and show some basic stuff for a client. Of course I use virtualization when testing my final bits etc.

Benefits and drawbacks

Having a local installation have several benefits:

  • You are running on the metal – i.e. no virtualization layer
  • Speed!
  • If you don’t have more than 4GB RAM then virtualization will be really slow
  • Visual Studio 2010 heavily uses WPF which requires a lot of your GPU. The virtualization layer will degrade the WPF performance
  • You don’t need to spin up and shut down VMs
  • Saves you a lot of disk space – one VM requires at least 20GB

Of course there are drawbacks. I would never go from developing on a local installation to production. Always test your code on a server OS!

SharePoint Foundation 2010 on Windows 7

I have installed SharePoint Foundation 2010 on my Windows 7 machine. I did not go for a full SharePoint Server installation. Most of the development can be done towards SPF and it makes a minimal impact on my client OS. But perhaps I go for a full SPS 2010 install once we have the final bits of it in June.

MSDN contains instructions on how to install SharePoint 2010 on a client OS, you need to extract the setup files and make some changes to the setup configuration file. With SQL Server Development Edition installed on my machine I installed a Server Farm, i.e. not the Standalone configuration. I also used domain accounts when I installed it, which required me to be connected to the domain during installation.

After the installation I’ve changed all SharePoint Services and SQL Services to be manually started to save some boot time. Emmanuel Bergerat has a great post on how to create Stop and Go scripts with PowerShell so that you quickly can start and stop all services. Starting these services and warming up my sites takes about 2-3 seconds on my machine equipped with an SSD (best gadget buy of 2010!)

Visual Studio 2010 RC and Team Foundation 2010 Basic

I use Visual Studio 2010 in combination with a Team Foundation Server 2010 Basic installation on my local machine. Using a local install of TFS is something I really recommend – never loose any of your local projects or files.

Visual Studio uses the GPU a lot so you will certainly have a better experience running without a virtualization layer. F5 debugging is no pain, it just takes a second to compile, package, deploy and start Internet Explorer.

Summary

If you have not tried to install SharePoint Foundation 2010 on your Windows 7 then stop reading right now and do it! It will increase your productivity immediately. The experience is awesome and together with RC of Visual Studio 2010 it’s just amazing.

SharePoint 2010 Wiki Pages displays the wrong content when passing Query String parameters

Posted at 2010-02-09 01:22 by Wictor Wilén in Web Parts , SharePoint 2010 with 1 comments.

While I was testing building some mashups using SharePoint 2010, Web Parts and SharePoint Designer I found an interesting bug.

Initial problem

Here’s what I did; I set up a Wiki Content Page (the new kind of Web Part Pages) in SharePoint 2010 that was supposed to be called with Query String parameter named ID which should be used by a Web Part. Another page contained items linking to this page using different integer values for the ID query string parameter like this:

http://server/SitePages/Item.aspx?ID=nn

My wiki pages was located in the Site Pages library within a Team site and when I clicked on one of the items I did not end up on my landing page ( Item.aspx in the sample above). Instead I ended up on random other pages in the library or received an SPException that the item did not exist. It took me a minute before I realized what really happened.

I was redirected to the item (page) in the library that had the Id of passed query string parameter. Strange! I did the same test but used a standard Web Part Page and then it worked as intended.

Actual problem

So I did a new test by creating a new Team Site. On the home page of the site /SitePages/Home.aspx I added a Web Part displaying just the Shared Documents library. This page has the Id=1. A second page is automatically created when you create the site, the How to use this library page, with an Id=2.

If I pass this request /SitePages/Home.aspx?ID=2 then I get the content of page 2 and vice versa. The strange is though if I call /SitePages/How%20To%20Use%20This%20Library.aspx?ID=1 I expected to see the contents of Home.aspx including the Web Part I added, which I did except for that the Web Part on that page was not present.

Developer Dashboard I opened up the Developer Dashboard which verified what I saw. When I called the /SitePages/Home.aspx?ID=2 I saw the contents of page #2 but It loaded the Web Parts from page #1. The image to the right proves that it added the Web Part to the page.

When passing the ID as a query string the Wiki Pages uses the Wiki content from the page with that ID provided in the Query String but uses the Web Parts from the page in the URL.

This certainly must be a bug…

SharePoint 2010 tools in Visual Studio 2010 violates basic naming conventions

Posted at 2010-02-07 03:35 by Wictor Wilén in Visual Studio , Web Parts , SharePoint 2010 with 3 comments.

The SharePoint 2010 Development Tools for Visual Studio 2010 is great and I really like the way that the project is built using the different artifacts. One thing really annoys me though and that is the way that the code is generated and named when you add items. For example if you create a project and then add a Web Part item to that project then Visual Studio will create a Web Part class with a namespace and class name like this:

namespace Wictor.CodeAnalysis.WebPart1 {
    public class WebPart1 : WebPart {
        // ---
}

As you can see the namespace and the name of the Web Part has the same name. This is a violation of one of the basic naming guideline rules (CA1724 if you run the code analysis in Visual Studio 2010). Although it works it will make your generated assembly having many different namespaces which makes it quite hard to work with. For each new item you will get a sub-namespace.

With tools like WSPBuilder I normally placed Web Parts within one namespace, controls in one and event receivers in another. This made the experience when working with the assembly easy.

If you now decide to change the namespace to something mode naming-convention-compliant such as below, then you need to update your Web Parts Control Description file (.webpart) and the SafeControl entry in the Package manifest.

namespace Wictor.CodeAnalysis.WebParts {
    public class WebPart1 : WebPart {
        // ---
}

Making all these manual corrections will likely make your project break at some time. So I guess we have to put up with this…but it is not good looking (so if you guys there in Redmond have a few nights over until VS2010 RTM, please fix this).

A request to the Microsoft SharePoint Product Team

Posted at 2010-02-05 03:30 by Wictor Wilén in Web Parts , SharePoint 2010 with 1 comments.

SharePoint is an amazing product and there are some fantastic opportunities to make awesome applications. It also has a great API which has had improved further in the upcoming SharePoint 2010 release. But there are several features available in the platform/API that just isn’t available to all of us, unless we sit in Redmond and are building the actual product.

There are so many classes or methods that are marked internal or sealed, that I really would like to use. I’m not going to nag about the search Web Parts this time, but instead focus on some classes that I really would like to be changed from internal to public.

When working with Web Parts and especially Editor Parts, where you can create your own interface for fiddling with the Web Part properties and its configuration. I really would like to be able, without writing numerous lines of styling code, to create neat looking Editor Parts that align with the rest of the Web Part tool pane. In particular I’m thinking about the BuilderButton class which is used to create the little ellipsis button, which you get a popup to edit the text in. Why on earth is that class sealed?

Dear SharePoint Product Team, you still have a few months until RTM of SharePoint 2010. Please make the BuilderButton public. And while you are there please go through the PropertySheetRow and Utlity classes and expose some of the methods or put them in a Tool Pane Utility class. Pure and simple…

Meanwhile I continue to use Reflector…

I am now an approved SharePoint 2010 Ignite instructor

Posted at 2010-01-25 06:30 by Wictor Wilén in SharePoint 2010 with 4 comments.

SharePoint 2010 A couple of weeks ago I participated in the SharePoint 2010 Ignite training and after a great, but quite hard, interview and discussion I have been approved as a SharePoint 2010 Ignite Developer trainer. I really look forward getting out there and teaching developers about all the awesome features and improvements in SharePoint 2010.

If you are interested in training don’t hesitate in contacting me. Together with AddSkills I have planned for a couple of SharePoint 2010 upgrade classes this spring.

Take care and see you out there…

SharePoint Bad Practices are still around!

Posted at 2010-01-19 10:14 by Wictor Wilén in SharePoint with 4 comments.

It is 2010 now and SharePoint 2007 have been out forever, it feels like it anyways. The last two years has been about best practices in SharePoint both for developers and IT-pros and especially the Disposing of SharePoint objects has been discussed in absurdum. So I guess we should have to talk about it - but guess what - we certainly do!

The reason I bring this up today is that I was about to join a new WFE to a farm and it failed once it started to provision the web applications. Using the logs I found the source of the failure, it was some kind of component that threw an unhandled exception when it was created. See logs below (I have cropped it a bit)

01/19/2010 14:58:58  8  INF                            Openning configdb so that I can join it at server 
01/19/2010 15:18:16 8 ERR Task configdb has failed with an unknown exception 01/19/2010 15:18:16 8 ERR Exception: System.Reflection.TargetInvocationException:
Exception has been thrown by the target of an invocation. --->
System.IO.FileNotFoundException: The Web application at http://SERVERXXX could not be found.
Verify that you have typed the URL correctly. If the URL should be serving existing content, the system
administrator may need to add a new request URL mapping to the intended application. at Microsoft.SharePoint.SPSite..ctor(SPFarm farm, Uri requestUri, Boolean contextSite, SPUserToken userToken) at Microsoft.SharePoint.SPSite..ctor(String requestUrl) at XXX.YYY.MyTimerJob.GetWeb() at XXX.YYY.MyTimerJob..ctor() --- End of inner exception stack trace --- at System.RuntimeMethodHandle._InvokeConstructor(Object[] args, SignatureStruct& signature, IntPtr declaringType) ... at Microsoft.SharePoint.Administration.SPWebApplication.Provision() at Microsoft.SharePoint.Administration.SPWebServiceInstance.Provision() at Microsoft.SharePoint.Administration.SPFarm.Join() at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.CreateOrConnectConfigDb() at Microsoft.SharePoint.PostSetupConfiguration.ConfigurationDatabaseTask.Run() at Microsoft.SharePoint.PostSetupConfiguration.TaskThread.ExecuteTask()

I opened up the source code to take a look what was going on in there. Fortunately this was no component that we have produced! This is what I found:

public class MyTimerJob: SPJobDefinition {
    static SPSite site = null;
    static SPWeb web = GetWeb();
    public static SPWeb GetWeb() {
        site = new SPSite("http://" + Environment.MachineName);   
        return site.RootWeb;
    }
...
}

So what is wring with this? Pretty obvious huh?

Not disposing objects!

This is a really bad example of not disposing objects. Both the SPSite and SPWeb are static members and are not getting disposed correctly and will hold the resources for as long as the object lives, in this case until the process terminates. You will likely not notice any degradation in performance if you have one of these objects but if you continue to build objects like this you will eventually trash the server.

SharePoint 2007 and SharePoint 2010, yup we are stuck with the same obstacles, have objects that are non-managed and uses connections to the database. These unmanaged are used by managed objects such as SPSite and SPWeb. The idea behind unmanaged code is that you should not have to care about object lifetime, destruction and garbage collecting but when we use unmanaged code we have to release these objects once we are finished with them and we should not use them any longer than we need to. Please do read through the Best Practices on MSDN before doing anything else!

Not testing the code!

This code had obviously not been tested thoroughly. The reason I got the exception was that during the web application provisioning objects like the timer jobs are being deserialized and that involves creating the object. Since the static objects are created the first time an object of that type is created and in this case it tries to attach to the web application that we are provisioning and not yet done with. So it will not find any web application and we get that exception.

Using the machine name!

The code tries to attach to the web application that has the address equal to the server name - that may be true on some occasions, but more often you have another address for your web application or use host headers etc.

What can we learn from all of this? I guess that we should all make sure that you and your colleagues know what to dispose and when to dispose it. If you are a trainer - please add an extra 10-15 minutes for this. Then test your code, not just on a single machine, but in a live environment resembling your production environment.

And by the way, since I had no control over the code causing the exception all I had to do was to deactivate the feature, install SharePoint and then activate it again.

For more bad practices head on over to Natalyas post.

Creating a SharePoint 2010 Ribbon extension - part 2

Posted at 2010-01-11 09:57 by Wictor Wilén in Web Parts , SharePoint 2010 with 1 comments.

This is the second post in my mini series on how to extend the SharePoint 2010 Ribbon. First post can be found here.

The goal with this excersice is to extend the Editing Tools Insert tab with a smaller Insert Web Part drop-down, so we don’t have to expand the whole Web Part Gallery to insert a Web Part.

In the last post we created a Visual Studio 2010 solution and added the drop-down to the correct tab in the Ribbon using the CustomAction element and some new SharePoint 2010 XML syntax.

Quick Add Web Part

Readers with good memory/eyes see that I made some more enhancements to the drop-down…

Step 3: Create the JavaScript Page Component for the Ribbon control

To make our new drop-down to be contextual, load the correct content and to react to clicks and actions we need to create a JavaScript Page Component object. This is not currently documented in any way that I have found on MSDN, so this might not be the correct way to do it once we get to RTM. But it works!

First of all we need to add a JavaScript file to our solution, this JavaScript file should be deployed in the _LAYOUTS folder. Right click the project and select Add->SharePoint “Layouts” mapped folder. Then add a JavaScript file to that folder so that the project looks like this:

JavaScript file added.

I recommend that you use a naming standard as I’ve done, have your file end i UI.js, since this is how the UI JavaScript files are named in SharePoint 2010. It doesn’t really matter but it’s easier for other developers to understand your code then.

Now it’s time for some heavy weight JavaScript hacking. Add the following code to your JavaScript file:

   1:  Type.registerNamespace('QuickAddWebPart.UI');
   2:  QuickAddWebPart.UI.QuickAddWebPartPageComponent = function () {
   3:      QuickAddWebPart.UI.QuickAddWebPartPageComponent.initializeBase(this);
   4:  }
   5:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.initialize = function () {
   6:      var ribbonPageManager = SP.Ribbon.PageManager.get_instance();
   7:      if (null !== ribbonPageManager) {
   8:          ribbonPageManager.addPageComponent(this.instance);
   9:          ribbonPageManager.get_focusManager().requestFocusForComponent(this.instance);
  10:      }
  11:  }
  12:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.refreshRibbonStatus = function () {
  13:      SP.Ribbon.PageManager.get_instance().get_commandDispatcher().
executeCommand(Commands.CommandIds.ApplicationStateChanged, null);
  14:  }
  15:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.prototype = {
  16:      init: function () {
  17:      },
  18:      getId: function () {
  19:          return 'QuickAddWebPartComponent';
  20:      },
  21:      getFocusedCommands: function () {
  22:          return [];
  23:      },
  24:      getGlobalCommands: function () {
  25:          return ['QuickAdd_Button', 'QuickAdd_Populate', 'QuickAdd_Query', 'QuickAdd_Add'];
  26:      },
  27:      isFocusable: function () {
  28:          return true;
  29:      },
  30:      receiveFocus: function () {
  31:          return true;
  32:      },
  33:      yieldFocus: function () {
  34:          return true;
  35:      },
  36:      canHandleCommand: function (commandId) {      
  37:          return true;
  38:      },
  39:      handleCommand: function (commandId, properties, sequence) {
  40:           return true;
  41:      }
  42:  }
  43:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.
registerClass('QuickAddWebPart.UI.QuickAddWebPartPageComponent', CUI.Page.PageComponent);
  44:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.instance = 
new QuickAddWebPart.UI.QuickAddWebPartPageComponent();
  45:  QuickAddWebPart.UI.QuickAddWebPartPageComponent.initialize();

This piece of JavaScript creates a new JavaScript object called QuickAddWebPartPageComponent (line 2) and is registered in the QuickAddWebPart.UI namespace (line 43). The object has a set of methods that is used by the Ribbon to query the component for which actions it supports and the object also has methods such as handling the actions and focus of the control. This is exactly how the native SharePoint 2010 UI objects behave.

There are a few important things to notice here:

  1. getGlobalCommands (line 24) returns an array of all our commands that we defined in the custom action in the previous post (QueryCommand, Command etc)
  2. There will be a lot of functionality added to canHandleCommand (line 36) and handleCommand (line 39) and other methods in the upcoming posts
  3. To create your own just replace QuickAddWebPart with your own string.

If we deploy this just as it is now, we won’t load the JavaScript file so we have to create a load control for this.

Step 4: Load the JavaScript

The easiest way to load our JavaScript is to create a delegate control and add that control to AdditionalPageHead.

First of all I add some more XML to the elements.xml file, just after our CustomAction:

Delegate Control...

This XML tells SharePoint to load the control and place it in the AdditionalPageHead. Note how I’m using the new Visual Studio 2010 tokens to replace the namespace and assembly name so I don’t have to write them and figure out the strong name. My control is called ScriptLoader and that control is added to the project as a new Class.

To load the control, see the code below, I use the ScriptLink.RegisterScriptAfterUI method, which is a part of the Microsoft.SharePoint.dll. I also make sure that I add some other necessary JavaScripts, that the page component and my code is dependant on.

   1:  namespace Wictor.QuickAddWebPart {    
   2:      public class ScriptLoader : WebControl {
   3:          protected override void OnPreRender(EventArgs e) {
   4:              SPRibbon currentRibbon = SPRibbon.GetCurrent(this.Page);    
   5:              if (currentRibbon != null && currentRibbon.IsTabAvailable("Ribbon.EditingTools.CPInsert")) {
   6:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Core.js", false, true);
   7:                  ScriptLink.RegisterScriptAfterUI(this.Page, "CUI.js", false, true);
   8:                  ScriptLink.RegisterScriptAfterUI(this.Page, "core.js", true, false);
   9:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Ribbon.js", false, true);
  10:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Runtime.js", false, true);
  11:                  ScriptLink.RegisterScriptAfterUI(this.Page, "SP.js", false, true);
  12:                  ScriptLink.RegisterScriptAfterUI(this.Page, "Wictor.QuickAddWebPart/QuickAddWebPart.ui.js", false, true);
  13:              }
  14:              base.OnPreRender(e);
  15:          }
  16:      }
  17:  }

To avoid that the scripts are loaded unnecessary I get the current Ribbon instance (line 4) and checks if the page has a Ribbon and if the Editing Tools->Insert tab is available (line 5). If you compile your project now it will fail, since the IsTabAvailable method is defined in the Ribbon class (not the SPRibbon class) which exists in the Web.Command.UI.dll assembly, so we need to add a reference to that DLL.

References

We also need to add this control to the Safe Controls. This is done by looking at the properties of the item that contains the elements.xml and selecting Safe Control Entries and then add our control to this collection.

 Properties

Fill in as below, note that I’m using the replaceable tokens here also.

Safe Control entry

Now we can build and deploy our solution. It still looks the same, there are no items in the drop-down yet. Until next part you can fiddle with the different methods in the Page Component and insert some JavaScript alerts to see when the methods are invoked (that’s how I figured out how it works…)

Until next time.

Creating a SharePoint 2010 Ribbon extension - part 1

Posted at 2010-01-07 02:04 by Wictor Wilén in Web Parts , SharePoint 2010 with 5 comments.

SharePoint 2010 contains numerous of improvements in the user interface and it has been built to be able to be extended. I guess that all of you have seen the Ribbon in SharePoint 2010 by now and probably even tried to add a button and fire away a Hello World JavaScript alert (it’s one of the HOLs available also). That’s quite an easy task. But doing some more advanced contextual and dynamic customizations to the Ribbon really makes you sweat!

For a couple of days I have wandered into the undocumented land of the SharePoint 2010 Ribbon and the JavaScript API’s and I thought I should share my experiences with you. It will be a couple of blog posts, so be sure to check back often – I’ll try to write them as fast as I can between writing the book.

As most of you now I’m quite fond of Web Parts and I don’t really like the new Web Part Gallery that pops out when you add a Web Part to a page in SharePoint 2010. It occupies so much of the screen. So why not building my own!

SharePoint 2010 Quick Add Web Part extension

This series will focus on creating a drop-down that lists all Web Parts in the site collection and then adds them to the page, just as you would do with the standard Web Part Gallery option. The idea here is to in the end be able to add some nifty extensions that helps the user adding correct Web Parts. This list might filter out a specific Web Part category or similar. I grabbed a short introduction video to what we are trying to achieve. Take a look:

As you can see it works really smooth – I still have to work on some improvements. But this simple extensions contains a declarative Ribbon, a JavaScript Ribbon component object, some SharePoint 2010 native JavaScript APIs and a delegate control all wrapped up as a feature. So let’s get started with the first part

Step 1: Creating the solution

To create this extension we use Visual Studio 2010 and create a new empty SharePoint project. It should be deployed as a fully trusted solution since custom actions is not supported in sandboxed mode. A declarative Ribbon extension is a CustomAction, just like you added custom actions in SharePoint 2007 – but with a whole new schema.

TIP: Check out the out-of-the-box Ribbon definition in the [SharePointRoot]\TEMPLATE\GLOBAL\XML\CMDUI.xml file

Step 2: Adding the Drop-down to the Ribbon

Empty elementNow it’s time to add the custom action, this is done by adding an an Empty Element item to the solution, called QuickAddRibbon. When you add this item to the solution a feature will automatically be added to your package called Feature1, rename it to something easier, let’s call it QuickAddWebPart. Then give it a meaningful name and description. Your solution should now look like this:

The solution

Now it’s time to add the actual Ribbon Custom Action, and this is the step that took me the longest time to get right. Intellisense helps you a lot and if you are like me, you like to take an iterative approach and try stuff as you hack along. This does not work in this case! You have to get your XML correct before deploying it, (almost) any  changes after that first deployment will not change if you redeploy it. It doesn’t appear even if you IISRESET and almost goes ballistic on the metal. If you need to change it then this is how to do it (read: they way it worked for me). First retract the solution, then remove the feature from your project, then add a new feature back and add the elements file back to the feature. Now you can once again deploy it to see your changes. I for sure hope that this changes in the future!

Ok, enough chatter, let’s see the code:

Ribbon Custom Action

As you can see I’m adding a custom action with the Location=”CommandUI.Ribbon”, this is what you would like to use if you would like to add extensions to the Ribbon. Then next thing to pay attention to is the Location of my extension (blue rectangle); I’m adding it to the Ribbon.EditingTools.CPInsert tab and the WebParts Group – all of these ids can be found in CMDUI.xml (see above). Then I append Controls, which means that I want all the controls in that group and finally _children to indicate that this is a new child element.

Note that this will only work for Wiki pages, standard Web Part pages has another id.

By now you can deploy this and see an empty drop down in the Insert tab when editing a Wiki page.

Wow, we got a drop-down!

In the next part we’re going to fill this drop-down with some cool JavaScripts and a server control.

Until next time.

I'm writing a SharePoint 2010 book

Posted at 2010-01-02 02:27 by Wictor Wilén in Personal , Web Parts , SharePoint 2010 , SharePoint 2010 Web Parts in Action with 8 comments.

A Book This is the first post for the year of 2010 and what could be better to start with than announcing that I’m writing a SharePoint 2010 book. More specifically I’m writing a book about SharePoint 2010 Web Parts development with the working title SharePoint 2010 Web Parts in Action.

This is a dream come true to me and I have been thinking about writing a book on and off for quite some time. I want to take my writing/blogging even further, it’s through writing that I educate and evolve myself. It makes me think twice and really make sure that I’m writing the correct stuff (who wants to be haunted down by all the readers and pros out there :-). So a book will be perfect to learn more about the SharePoint 2010 platform and dig down even further in Web Parts development.

Web Parts has been one of my favorite topics in SharePoint – I really like the concept of making self-contained applications that can be configured by the end-users and optionally connected to create mashups. I written a bunch of posts on the topic and published two Codeplex projects; ChartPart and Tweetpart. Web Parts is one of the subjects that almost all SharePoint developers have been working with and it has its difficulties and pains. I hope I can get down all my experience, ideas and troubleshooting into this book and that it gets great feedback and usage.

The book is going to be published by Manning Publications and I really want to thank them for making this possible! Manning got a really interesting concept with their MEAP program (Manning Early Access Program), which allows you to buy the book at a discounted price even before it’s complete and published. Then those buyers have an opportunity to comment on the book so far and possibly influence the author. This book will during the spring become a part of the MEAP program – so watch out for further announcements. Manning have a nice line-up of books coming this year including SharePoint Workflows in Action by Phil Wicklund, SharePoint 2010 Site Owners’ manual by Yvonne Harryman and SharePoint Server 2007 Survival Guide by Penelope Coventry et al.

I have already started writing and I’m really satisfied so far. If you have any particular questions or things that you would like to have answered then don’t hesitate to contact me!

Happy new year!

Summing up the year of 2009 and embracing 2010

Posted at 2009-12-28 04:48 by Wictor Wilén in Personal , SharePoint , Windows Mobile , Windows 7 , CodePlex , SharePoint 2010 with 3 comments.

The year of 2009 is about to close and it’s time for me to summarize this year, as I’ve done for the last few years (2006, 2007 and 2008). This year has been one of the most inspiring and exciting years for me in a very long time. I have been doing so much fun stuff this year.

The most significant change has been starting to work for my new employer Connecta (after nine years at basically the same employer). I needed some new challenges and I now work with some really talented people from whom I learn and share so much. As you readers know, it’s all about SharePoint for me and I have done some awesome projects this year that I’m proud of and really looking forward to some SharePoint 2010 gigs. I also finally got my MCT certification and already scheduled a number of courses for next year, looking forward to meet some aspiring SharePoint students!

Another really cool thing is that just a few weeks ago I signed a contract with Manning Publications about writing a book on SharePoint 2010, first chapter is due in a few days. This is something that I wanted to do for some time; it’s hard work but it makes me get even better – and that’s why I’m in the game. More details on the book in an upcoming post…

Blogging

I continued to blog about things that I’ve found interesting – not as much as I had hoped for. I’ll try to get better next year, even though focus will be on the book for the first few months. But if I take a look at the statistics it looks like it has been a great year – thank you all new followers. The most popular post this year has been:

  1. Running SharePoint on Windows 7 – one of the first things I did on Windows 7
  2. Creating SharePoint 2010 workflows with Visio 2010 – awesomeness in a box
  3. SharePoint Service Pack 2 known, found and experienced problems – there are always problems
  4. Web Part Properties - part 2 - Editor Parts – great response on this series
  5. Web Part Properties - part 3 - the .webpart file – a runner up…

SharePoint Community

I’ve made a big commitment to the SharePoint community this year – and I like it, I like it a lot! It has been so fun and rewarding commenting, tweeting and meeting with the incredible SharePoint community. Can’t imagine any other community that has so much fun together! Unfortunately I missed the highlight conference in Las Vegas and the chance to listen and meet the rest of you, due to the change of employer. I hope I can make it for another year.

Here in Sweden we started the SharePointCommunity.se site to gather all SharePoint interested people and the Swedish SharePoint User Group under one umbrella and we have reached close to 500 members. The User Group here in Sweden have had some great meetings and presentations with a great number of people. Thank you again to all speakers and participants. Next year will be awesome!

Speaking engagements

I’ve been fortunate to have had a few presentations for the Swedish SharePoint User Group (in February two sessions and one in September) but the most fun presentations I’ve had was the one in Copenhagen at the first European SharePoint Saturday and the one at the Swedish SharePoint and Exchange Forum. It was awesome meeting all these cool people I only have had 140 characters discussions with. One of my first assignments with my new employer was a SharePoint 2010 seminar which we presented on a huge cinema screen in an almost full theatre – just loved it! I hope I will get more opportunities in 2010 do some more SharePoint love!

Personal Projects

As always I fiddle around with SharePoint as much as I can and I finished version 2 of ChartPart, which you can find on Codeplex. ChartPart v 1 had about 10.000 downloads and version 2 has had close to 3.000 now (and 4.000 in beta). Together with Keith Dahlby I got the SharePoint Extensions Library out – and I’ve received very good feedback on it. Two other projects also ended up on Codeplex; Windows Live ID Authentication for SharePoint and TweetPart. I will try to get these updated to support SharePoint 2010 to 100%.

Last years predictions

Last year I did some predictions, as I’ve done now for a couple of years. I guessed that 2009 will be a year of constant betas – and man I was right. Windows 7 betas, Office 2010 betas and SharePoint 2010 betas has been making my days wonderful/peculiar this year. I predicted that Office 14 would hit the streets – now we now that we won’t get the final bits until mid 2010. I was right about Internet Explorer 8 and Windows 7. I also predicted that Microsoft would go for more open source projects and I think they very well have lived up to that – just take a look at Codeplex where Microsoft have released a great amount of awesome projects.

Predictions for 2010

What about 2010 then? We all now that Microsoft is focusing everything on Office 2010 and SharePoint 2010 and they will continue grow even stronger. But I think that during the later parts of 2010 Microsoft will have something extraordinary coming in Windows Mobile 7. They must have, otherwise it’s game over for sure for Windows Mobile.

Another thing we will see starting emerge from Redmond is a new Internet Explorer, it’s loosing market shares, so I expect some major improvements in standards compatibility and of course some new creative thinking.

Thank you and a happy new year

That’s all folks. The last year of this decade is over and it’s time to grab the bull by it’s horn and face a new one…

Happy new year!

Improve your SharePoint 2010 applications with monitoring using SPMonitoredScope

Posted at 2009-12-21 04:36 by Wictor Wilén in SharePoint 2010 with 2 comments.

SharePoint 2010 comes equipped with a set of new tools to improve the monitoring of your custom applications, there are built-in functionality to check how long your operations take, how many SQL Server calls are done etc. All this is logged and can be visualized in the Developer Dashboard.

Developer Dashboard

Another good thing with this is that it’s not something that just automatically is there but you can also hook yourself into the monitoring and the actual Developer Dashboard.

Monitoring your custom code

There are many cases when you run into trouble in production, due to the fact that some parts are running slow or even makes your entire farm run on its knees. This can be because you are running a SQL query that takes forever, a never-ending loop or a Http request that takes just too long. In previous versions of SharePoint you either had to write custom code to log these conditions or write to the ULS logs, I even wrote my own event logging provider once to monitor the executed code.

Monitored Scopes In SharePoint 2010 everything is executed under a so called Monitored Scope. Each scope has a set of Monitors that measures and counts calls and timings – and this is what get’s logged in the Developers Dashboard. If you take a look at the image on the right you can see that the calls are nested and each row represents a monitored scope. At the end of each scope all monitors are evaluated and if anyone of the exceeds their limits this is logged (or if you have turned on verbose logging it always is logged).

You can very easily make your own monitored scope – and I think that you should do that from now on in all your SharePoint 2010 projects. It will help you one day!

For example if I have a Web Part that is running an operation that could take some time, for example a web service call, I could write code like this to start my scope:

   1:  protected override void OnPreRender(EventArgs e) {
   2:      using (SPMonitoredScope monitoredScope = 
   3:             new SPMonitoredScope("Long Call")) {
   4:          longCall();
   5:      }
   6:      base.OnPreRender(e);
   7:  }
On line 2 i create a new object of the type SPMonitoredScope and give that scope a name (“Long Call”). Inside that scope my code that might take long time is running (line 4). If the Developer Dashboard is turned on, this scope will be visible, see image below on the third line.

image

This is a very easy way to improve the logging of your application.

Worth noticing is that this will not work for Sandboxed applications, they run in a separate process.

Custom monitors

Just logging your scopes in the developers dashboard is one thing but you also sometimes would like to make sure that you monitor how many times this code is executed. Let’s say that you are using a web service that you pay per use of, then it would be nice to monitor how many times you are querying the web service and optionally refuse usage if it exceeds your budget.

As I said before SharePoint 2010 always adds a set of monitors to your scopes (the parent scope actually) that monitors time, SQL queries etc. And you can do the same.

All you have to do is to create a new class and inherit from ISPScopedPerformanceMonitor and then implement that interface. To get this monitor into your scope you have to pass it as a parameter to your SPMonitoredScope constructor like this:

using (SPMonitoredScope monitoredScope = 
       new SPMonitoredScope("Long Call", 1000, new TheMonitor())) {...}

You can pass in as many monitors as you like.

In the code above your custom monitor is TheMonitor and it could look like this:

   1:  public class TheMonitor: ISPScopedPerformanceMonitor{
   2:      static int s_times;
   3:      static TheMonitor() {
   4:          s_times = 0;
   5:      }
   6:      public TheMonitor() {
   7:          s_times++;
   8:      }
   9:      public void Dispose() { }
  10:   
  11:      public string Description {
  12:          get { return "The Monitor"; }
  13:      }
  14:   
  15:      public string Name {
  16:          get { return "TheMonitor"; }
  17:      }
  18:   
  19:      public string RenderValueForWeb() {
  20:          return string.Format("MONITOR: {0}",s_times);
  21:      }
  22:   
  23:      public object Value {
  24:          get { return s_times; }
  25:      }
  26:   
  27:      public bool ValueIsExcessive {
  28:          get { return s_times > 5; }
  29:      }
  30:  }

This monitor class will count each time this monitor is called (in the constructor, line 7) and if it’s called more than 5 times the threshold value has been exceeded. (Note: this implementation will not work in production and contains no threading support). At the end of each scope, when the SPMonitoredScope is disposed it will check all monitors using the ValueIsExcessive and if that method returns true it will be logged to the ULS logs.

This is an excerpt from a ULS log using the monitor above:

Entering monitored scope (Long Call)
Leaving Monitored Scope (Long Call). Execution Time=999.885180937801
____TheMonitor=15
____Execution Time=999.885180937801

 

I hope this post inspired you to produce code that can be monitored more easily using the SharePoint 2010 built-in features.

Merry Christmas to you all!

Swedish SharePoint User Group December 09

Posted at 2009-12-15 02:23 by Wictor Wilén in SharePoint , Presentations with 0 comments.

Yesterday we had a Swedish SharePoint User Group meeting, hosted by Connecta (yes, my new employer). We had a new record with number of participants, over 60 interested SharePointers of all kinds showed up to listen to MVP Göran Husman, Humandata, talk about the news in SharePoint 2010 and Peter Karpinski, Microsoft Services, talk about how to do Rapid Application Development with SharePoint 2010, SharePoint Designer 2010, Visio 2010 and InfoPath 2010 and how to script you SharePoint 2010 installs. Thank you for great shows and thanks to everyone who showed up.

I hope we can continue this trend and have as many people in each meeting and there will be meetings in other cities than Stockholm during next year.

MVP Göran Husman Peter Karpinski
Mattias Karlsson, MVP Tobias Zimmergren, Joakim Hägglund and Tony Reistano Peters laptop after SSD quality testing...

I also did a short intro presentation about the survey we had earlier this autumn about the UG meetings. And from that survey I think that we will have meetings every other month or so (depending on how much people will engage). A lot of new people was interested in having a session and/or wanting to host future meetings – expect to be contacted soon for next meeting. We discussed having a meeting during Techdays 2010 in March and can hopefully squeeze one more in before that.

Post will be updated when I have Görans and Peters presentations and Peters Awesome Install SharePoint With No Hands scripts.

Four interesting changes to the SharePoint Foundation 2010 API

Posted at 2009-12-13 12:40 by Wictor Wilén in SharePoint 2010 with 5 comments.

Working with SharePoint 2010 is really a joy, you stumble upon great things all the time. The API has not had any revolutionary changes to be backwards compatible; but small changes here and there, both publically visible and internally, really makes the API better than before.

SPListItem.SPContentTypeId

To get the Content Type Id of an SPListItem you had to first get the SPContentType from the SPListItem.ContentType and then get the Id of the content type. This method was one marked as internal in version 12, but is now marked 14. It’s those little things. There are actually a lot of previously internal properties and methods that now are public, for example the CanBeDisplayedInEditForm property on the SPField class.

SPListCollection.TryGetList(string listTitle)

Last year I wrote a post about this one and now it’s there. No need to encapsulate your code with try-catch blocks when trying to get a list using it’s name. TryGetList will return null if the list does not exist. Thank you guys, up there in Redmond!

SPWebPartManager disposes the SPWeb object

One change that is really great. When using the SPWebPartManager or the SPLimitedWebPartManager you previously had to manually dispose the SPWeb object before disposing the Web Part manager, now that’s done when disposing the SPWebPartManager or the SPLimitedWebPartManager. This will save a lot of people a lot of memory leaks.

SPField.ListFieldUsedIn(…)

This is an interesting one, using this method you can find out which sites and lists a specific field is used. The method returns a collection of SPFieldTemplateUsage objects, which contains Guids of the list and site Id’s. One thing that also is interesting with this one is the usage of the templated ICollection instead of an array or custom collection.

There are of course a lot more, but these four I did find during my excavations this weekend. Have you found any favorite change except the obvious ones?

web tracker
msfeedicon The one and only feed enhancement utility for Internet Explorer 7.
Read more...