SharePoint Themes and how to make them work

November 11, 2010 Leave a comment

I’ll start at the end because I think I’m going to forget this the most often:

How to get a CSS file to be compiled by the theme engine

First of all, use the CssRegistration tag.  You’ll be happy you did when you don’t have to fight with SharePoint to get your CSS file to link properly.

 <SharePoint:CssRegistration Name="<%$SPurl:~SiteCollection/Style Library/en-us/Themable/MyHome.css%>" After="corev4.css" runat="server" />

The “<%$SPurl…” ensures that the url points to the current version (themed or non themed) of the css file.  Be sure to put this tag right after the SharePoint:CssLink tag, I’ve tried putting it in other places and for some unknown reason it breaks things pretty badly.

Place your CSS file under the themeable directory under the Style Library like the URL shown in the CssRegistration tag.

And now the secret sauce – CHECK IN AND PUBLISH YOUR CSS AND IMAGE FILES!

The theme engine will not pick up any non-published versions, you MUST check in your CSS and image files.

Finally, apply a theme – any old theme.

You’ll notice that when you apply the theme, and look at the page source your css files will have moved into a different directory:

 <link rel="stylesheet" type="text/css" href="/_catalogs/theme/Themed/9262B884/MyHome-4277C871.css?ctag=44">

Weird huh?

When you applied the style, the theme engine picked up all the style sheets and images and performed its magic on them.  Then it saved them to this separate location.

This means that any changes you now make to your original css or image files will not be reflected in your newly themed site – yes, that’s right, you need to go back and reapply your theme to the site so the theme engine will recompile the CSS and image files.  Man that’s annoying isn’t it?!

Using themes in your CSS files

Below are a list of the theme commands you can use in your CSS file.  The commands will replace CSS attributes or recolor images as appropriate if used properly.  But first, there’s a mysterious comment at the top of the corev4.css file that I’ve noticed:

/* _lcid=”1033″ _version=”14.0.4762″
_LocalBinding */

I don’t know what it does, and as far as I can tell, this page is the first reference to this comment anywhere on the interwebs.  For now I’ll leave this at the top, because it’s there in corev4.css and I want my style sheet to be just like corev4.css when it grows up.

Next – there are a few commands that can be used to theme-up your stylesheet:

ReplaceColor(themeColor) – should be put before a color attribute (obviously), this will replace the attribute color with a color from your theme.

ReplaceFont(themeFont) – this guy works like ReplaceColor, except with fonts.

RecolorImage(themeColor, method, includeRectangle) – should be put before an image reference – ie. url(<image url>).  This will color the image in the manner specified.  The only required parameter is the color, the other 2 params are optional:

themeColor – this one’s obvious, the color to use to re-color the image.
method – options here are: Filling, Blending, Tinting
includeRectangle – defines the section of the image to recolor i.e. {x:0,y:0,width:15,height:15} defines a rectangle starting at 0, 0 pixels, and is 15px high by 15px wide.

All of the above is pretty self-explanitory with the exception of the method parameter on the RecolorImage – for this, I refer you to an excellent blog post from Microsoft’s SharePoint team in which he shows examples of each recolor method, as well as all the permutations of the different colors.

One last thing – I’ve found themes to be not an extremely awful experience, just a painful one.  However, they can be useful every once in a while in limited situations.  For these limited situations it’s probably necessary to undo all the theming that’s in the corev4.css so that you can implement themes for only the elements that you wish.  The ThemeOverride.css stylesheet will override all the style rules in corev4.css, so that no theme colors or fonts will display.

To use the ThemeOverride.css stylesheet, just insert it between corev4.css and your custom css like so:

      <SharePoint:CssLink runat="server" Version="4" />
      <SharePoint:CssRegistration Name="<%$SPurl:~SiteCollection/Style Library/en-us/Themable/ThemeOverride.css%>" After="corev4.css" runat="server" />
      <SharePoint:CssRegistration Name="<%$SPurl:~SiteCollection/Style Library/en-us/Themable/MyHome.css%>"
           After="<%$SPurl:~SiteCollection/Style Library/en-us/Themable/ThemeOverride.css%>" runat="server" />

Be sure that you specify the ThemeOverride.css in the After attribute of your custom stylesheet.  Otherwise the ThemeOverride.css will be moved after your custom style sheet and will override all of your beautiful CSS work.

Categories: SharePoint, UI

The path specified cannot be used at this time. Exception from (HRESULT: 0x80070094)

November 8, 2010 2 comments

Recently, while attempting to deploy a new WSP file to my dev environment, I was presented with another exceptionally helpful error message:

Error: The path specified cannot be used at this time. Exception from (HRESULT: 0x80070094)

It took me a little bit to figure out, but basically, I reset the SP Timer service and all was well again.

What’s interesting is that even after getting this error, SharePoint claimed that the solution was properly deployed – though I didn’t want to take any chances with finding bugs due to a partially deployed solution.

Categories: Uncategorized

Setup incoming email for your SharePoint development VM

September 3, 2010 Leave a comment

So today I was trying to figure out how to debug an event handler on an email-enabled list.  My dev environment is running on a VM on my laptop so I didn’t really have an exchange server I could hook up to.  So, configuring the SMTP service on my Windows 2008 machine was the way to go.

In server manager, under features, click Add Feature, then select the SMTP service.  Accept the feature dependencies and finish the install.



Open the IIS 6.0 manager, and right-click your new SMTP Virtual Server node, then click properties.  Under access, ensure your authentication method is set to annonymous and your relay restrictions allow anyone.  Remember, this is just a development setup, so hopefully noone will be hacking into your new SMTP server to send out spam for Viagra.

Also, you may want to assign an alias for your domain, but that’s not required.

Next, go into Central Administration -> System Settings -> Configure incoming e-mail settings.  Select advanced settings, and at the bottom plug in your machine name and the email drop folder ‘c:\inetpub\mailroot\drop’ then hit OK.

Once that’s done we just need to enable the list to receive emails.  Just open your list (or create a new one) and go to list settings.  Under the communication section is a link for Incoming e-mail settings.  Select that and choose the settings appropriate for your list.  Note that you may want to configure this through a feature receiver or a list deployed in your solution (after all, isn’t that what we’re here for?).

Now lets deploy and debug our event receiver.  In your Visual Studio solution, click run to deploy and begin debugging the solution.  Now, although normal list event receivers are run on the w3wp.exe process, list event receivers running on e-mail enabled lists will be run by the OWSTIMER.EXE process, so use the Debug -> Attach to Process… option to find it.  You may need to check the Show processes from all users option.

Once we’ve got our event wired up and the proper process being debugged, we just need to fire up and email and see if this thing works.  So, unless you have an email client (or want to install one) on your virutal machine, back out to your host machine.  You’ll need to make sure that your host machine can connect to your VM over the network.  Now, in Outlook, go to Tools -> Account settings… In the email tab, click on New… and select the Microsoft Exchange, POP3, IMAP or HTTP option.  On the next screen, don’t enter anything, but check the box at the bottom of the screen specifying that you want to manually configure your settings, and next choose the Internet email option.

On the next screen you’ll be asked for a bunch of settings for the SMTP server, your email address, user name and password. The important thing here is to set the SMTP server to your VM server address, we don’t have a POP3 or IMAP server set up on the machine, so incoming mail won’t work, but that shouldn’t matter since we just want to send mail to our new SMTP server.  Enter in some test email, and the username and password of your development user.  Click the Test Account Settings… button and you should receive the results I got below.

If you didn’t, it’s most likely because your VM isn’t responding at the address you plugged in for your Outoing mail server (SMTP) value.  Remember, this value doesn’t need to have the domain your VM is on, it just needs to be able to find the SMTP service at that address.  One extra way to test it is to open the mail drop folder (c:\inetpub\mailroot\drop) on your VM and watch the test email file show up there, then promptly disappear when the timer job runs.

Now just create a new email and send it to your new list email address – be sure to use the new account you just created.  Type in your subject and email body and send away.

Categories: SharePoint

WritableBitmap finally usable, and very cool

I just found a very cool set of extension methods that actually make Silverlight’s WritableBitmap class usable.

The Codeplex project

It’s going to allow for a much faster particle generator as well as some other very cool effects.

Other links:

http://blogs.silverarcade.com/silverlight-games-101/15/silverlight-blitting-and-blending-with-silverlights-writeablebitmap/

http://kodierer.blogspot.com/2009/11/drawing-shapes-silverlight.html

Categories: Uncategorized

A Silverlight tree control that only loads content when needed…

I’ve had to re-write this thing a few times now, so I thought I’d make a generic one and post it here for my reference.  The control is a normal tree control that will query child elements from a web service or some other thing when that node’s parent has expanded. So, when the control is first loaded, we will go out and query for the nodes that should show at the root of the tree.  Next, we want to query for all the children of those root elements and stop there.  Once a user decides to expand one of the nodes, we have all of its children, so that’s fine, but we want the children’s children (or 2 down).  That way the user doesn’t need to wait 2 or 3 seconds for the node’s contents to populate.

 

There’s a few things to doing this that are not really straight forward.  The first and most obvious is getting an event raised when a node is expanded.  To do this, we need to customize the TreeView and TreeViewItem.

 

We’ll start with the TreeViewItem:

1:    public class CustomTreeViewItem : TreeViewItem {
2:      public CustomTreeView ParentTreeView { set; get; }
3:      public CustomTreeViewItem() {
4:        this.Expanded += new RoutedEventHandler(CustomTreeViewItem_Expanded);
5:        this.Collapsed += new RoutedEventHandler(CustomTreeViewItem_Collapsed);
6:        this.MouseLeftButtonDown += new MouseButtonEventHandler(CustomTreeViewItem_MouseLeftButtonDown);
7:      }
8:      void CustomTreeViewItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
9:        this.ParentTreeView.InvokeContainerClicked(sender, e);
10:      }
11:      void CustomTreeViewItem_Collapsed(object sender, RoutedEventArgs e) {
12:        this.ParentTreeView.InvokeContainerCollapsed(sender, e);
13:      }
14:      void CustomTreeViewItem_Expanded(object sender, RoutedEventArgs e) {
15:        this.UpdateLayout();
16:        this.ParentTreeView.InvokeContainerExpanded(sender, e);
17:      }
18:      protected override bool IsItemItsOwnContainerOverride(object item) {
19:        return item is CustomTreeViewItem;
20:      }
21:      protected override DependencyObject GetContainerForItemOverride() {
22:        return new CustomTreeViewItem();
23:      }
24:      protected override void PrepareContainerForItemOverride(DependencyObject element, object item) {
25:        CustomTreeViewItem treeViewItemExtended = (CustomTreeViewItem)element;
26:        treeViewItemExtended.ParentTreeView = this.ParentTreeView;
27:        base.PrepareContainerForItemOverride(element, item);
28:      }
29:    }

 

The routed event handlers are set up upon construction of the object and when fired, they call the appropriate event on the ParentTreeView.  The other GetContainer & PrepareContainer methods just wire up the control for customization.

 

Now the TreeView:

1:    public class CustomTreeView : TreeView {
2:      protected override bool IsItemItsOwnContainerOverride(object item) {
3:        return item is CustomTreeViewItem;
4:      }
5:      protected override DependencyObject GetContainerForItemOverride() {
6:        return new CustomTreeViewItem();
7:      }
8:      protected override void PrepareContainerForItemOverride(DependencyObject element, object item) {
9:        CustomTreeViewItem treeViewItemExtended = (CustomTreeViewItem)element;
10:        treeViewItemExtended.ParentTreeView = this;
11:        base.PrepareContainerForItemOverride(element, item);
12:        this.InvokeRootItemCreated(element, new RoutedEventArgs());
13:      }
14:      public event RoutedEventHandler RootItemCreated;
15:      internal void InvokeRootItemCreated(object sender, RoutedEventArgs e) {
16:        if (this.RootItemCreated != null)
17:          this.RootItemCreated(sender, e);
18:      }
19:      public event RoutedEventHandler ContainerExpanded;
20:      internal void InvokeContainerExpanded(object sender, RoutedEventArgs e) {
21:        RoutedEventHandler expanded = ContainerExpanded;
22:        if (expanded != null)
23:          expanded(sender, e);
24:      }
25:      public event RoutedEventHandler ContainerCollapsed;
26:      internal void InvokeContainerCollapsed(object sender, RoutedEventArgs e) {
27:        RoutedEventHandler collapsed = ContainerCollapsed;
28:        if (collapsed != null)
29:          collapsed(sender, e);
30:      }
31:      public event MouseButtonEventHandler ContainerClicked;
32:      internal void InvokeContainerClicked(object sender, MouseButtonEventArgs e) {
33:        MouseButtonEventHandler clicked = ContainerClicked;
34:        if (clicked != null)
35:          clicked(sender, e);
36:      }
37:    }

 

This class is the control we’ll use, so we need to expose the TreeViewItem’s events through here.  Again, the other methods just wire up the control for customization.

 

The second not-so-obvious item is hidden within the CustomTreeViewItem.CustomTreeViewItem_Expanded() method.  Notice the this.UpdateLayout() call?  Don’t forget this little step before you fire the event or you’ll pull your hair out trying to figure out why you’re getting NPE’s everywhere.  Basically, before expanding the node, you may have assigned children to the item, but the ItemContainerGenerator will not have generated the TreeViewItem yet.  If you debug it, you can take a look at the ItemContainerGenerator’s _awaitingLoadIndices (Non-Public member).  You’ll see it has a few items in it, and every call you make to ContainerFromItem() or ContainerFromIndex() will result in NULL.

 

Ok, everything else is pretty simple, so I’ll just end this here.  The sample I’m including has a dummied Timer and item generation method that you’ll want to replace with your web service call (or whatever other call you need to make).

 

Enjoy!

Download the full project here

Renaming a SharePoint dev server

When setting up a dev server (or any server for that matter) you should always rename the machine after you’ve installed Windows and before setting up any other applications.  This is particularly true if you’re setting up a SharePoint server, as renaming the server after you’ve set up SharePoint has disastrous effects.

 

However, if you’ve forgotten to rename your server (like I did) and you just installed SharePoint and are getting sick of typing in names like http://win-87efgyaklq (like I am), there is a way out – as long as you’re willing to part with your content databases.  There’s probably a way to do it without losing all your content, but I haven’t figured that one out yet…

 

Step 1. Detach the SharePoint server from the farm.

Open the SharePoint Configuration Wizard and select “Disconnect from this server Farm”.

 

Click Next, Yes, then Finish.

 

Step 2. Rename the Server

Don’t forget to do it this time… it’s the whole reason we’re going through this mess.

Now we want to recreate the farm, but first we want to clean out all the content databases, since we really can’t use them (they have references to the old machine name).

 

Step 3. Delete the SharePoint content & configuration databases

Fire up SQL Server Management Studio and log into your database.  Open the Object Explorer Details and highlight all of your SharePoint Databases.  Note my Forms Based Auth. database below can stay as we can still use this after the machine name changes.

 

Right Click -> Delete.  You’ll probably want to check the box that says to close all existing connections before deleting otherwise you’ll get a few errors (SharePoint keeps DB connections in its connection pool open for a while).

 

Step 4. Recreate your farm

Fire up your SharePoint configuration wizard again and this time you want to create a new farm.

 

And that’s it, you’re done.  Well, after you create your web app and site collections, but you should already know how to do that – right?

Categories: SharePoint

"Simple" Particle Generator Using Silverlight 4… Part 1

Since this is my first blog post, I thought I’d start with something simple.  Today I’m going to walk through creating a particle generator using Silverlight 4.  Now, I have a few requirements when creating this thing, and if anyone has any other stuff that I didn’t think of, feel free to call me out.

  1. The most extremely, very, super important requirement is that it has to be fast.  If this thing is going to be usable at all, we’ll need it to be able to scale up to animating thousands of particles at frame rates of over 60fps.
  2. The control has to be customizable.  We want people to be able to apply their own algorithms for how the particles move (or don’t move), what they bounce off of, etc.
  3. Oh, now I got a bit ahead of myself – the particle generator must be a control in a separate class library.  One that can be referenced in any project and dropped into a page, control or otherwise.
  4. Now I’m going to throw a little wrench in and say that we want to animate the particles in 3D.  Now, I know what you’re thinkin’ (or maybe I don’t), but it’s not that big a deal – Silverlight has some nifty tricks that will help us out with this one.

Now to accomplish the first task, we’re going to do a few things that are a bit different than how we would normally play with Silverlight. First, most of our control is going to be written in C#, with only bits and pieces done with XAML.  Second, we are going to use structs wherever it makes sense instead of using classes.  This keeps our memory management simple, and prevents the interpreter from needing to dereference objects.  For similar reasons, we want to use Arrays instead of lists or any other data structure as much as possible.  Third, we’re going to make this sucker multi-threaded.  Now, this has some limitations that I’m not very fond of, but keeping the majority of our calculations off the UI thread will make things much faster.

The second and third tasks are fairly straight forward, but we’ll walk through how to do them and why later.  The fourth requirement however, is a bit tricky.  If you’re new to Silverlight, I’m not exactly sure why you’d be reading this, but there’s a transformation you can apply to your controls that will move them in 3D space, then project them back into 2D to fit on your screen.  This is the part that Silverlight will do for us, so that makes our lives much simpler.

However, Silverlight is basically a 2D application, and has no other real facilities for doing complex calculations in 3D space, so this means we’ll need to create the objects, and do the calculations ourselves.  Luckily, this is a very well understood area of mathematics, so be prepared to put your Trigonometry hat on.

The basics of a particle generator are very simple:

  1. Create a bunch of UI elements along with a few other variables to track direction, speed (together called velocity) and a few other variables.
  2. Create a timer that will fire a few times a second (well, hopefully many times per second) to move your particles.
  3. Each call of the timer will loop through all the elements and update the velocity (speed and/or direction), then apply the velocity to the element’s current position.

Now, normally a super-duper simple rendition of this is actually pretty simple to write (probably about 50 or so lines of code for the entire deal).  But some of our requirements put a big dent into that “super-duper simple” description – so we’re going to modify that algorithm I just ran through (note, this algorithm will change many times over the course of this little tutorial, so don’t worry if you think this sounds too simple):

  1. Create a bunch of UI elements along with a few other variables to track direction, speed and a few other variables.
  2. Create a timer that will fire on a separate thread a few times a second (well, hopefully many times per second) to move your particles.
  3. Each call of the timer will loop through all the elements and update the velocity, then apply the velocity to the element’s current position variable.
  4. Submit a job to the UI thread to apply the current position to the projection transform of the UI element.

Note the timer in step two: every time it ticks, the timeout method will kick off on a different thread other than the UI thread.  Now threading in Silverlight is a bit different than threading with normal Windows applications – if we’re not on the UI thread, we cannot touch any UI controls.  Hence the changes to step 3 and 4: calculations done on the timer thread are saved to a set of variables, then we submit a job to the UI thread (through the control’s dispatcher) that will update the elements on the form.

Now that we’ve got the basic algorithm figured out, lets dig into some code and see how this works…

Open up Visual Studio, then select Silverlight on the left and the Silverlight Class Library on the right:

Name the project what ever you’d like.  I’ve named mine “ParticleGenerator”.  I know, creative right?  Be sure to select Silverlight 4 for the runtime, though with some minor tweaks you could probably do this with Silverlight 3 as well.
Delete the random class that the template provides for you.  We’re going to start by creating some of the supporting classes (and structs) we’ll need to keep track of things: Point3D & Particle.
Before we get into the code, I have one disclaimer: to keep this blog as short as possible, I haven’t added in any error handling.  I could rant a little bit about how important error handling is, but again, I’m attempting to keep this short.
Point3D
The Point3D struct will serve two main functions.  It will be a normal point in 3D space, holding the X, Y, and Z positions as well as some functions that allow us to move the point around.  It will also be a vector.  A vector is a point in reference to something else.  So we can use a vector to hold our velocity.  More on this in a little bit.
1:  using System;
2:  namespace ParticleGenerator {
3:    public struct Point3D {
4:      public double x { get; set; }
5:      public double y { get; set; }
6:      public double z { get; set; }
7:      public double length {
8:        get {
9:          double returnValue;
10:          double x2 = this.x * this.x;
11:          double y2 = this.y * this.y;
12:          double z2 = this.z * this.z;
13:          returnValue = Math.Sqrt(x2 + y2 + z2);
14:          return returnValue;
15:        }
16:      }
17:      public void add(Point3D p) {
18:        this.x += p.x;
19:        this.y += p.y;
20:        this.z += p.z;
21:      }
22:      public void subtract(Point3D p) {
23:        this.x -= p.x;
24:        this.y -= p.y;
25:        this.z -= p.z;
26:      }
27:      public void scale(double n) {
28:        this.x *= n;
29:        this.y *= n;
30:        this.z *= n;
31:      }
32:      public void lerp(Point3D p, double ratio) {
33:        if (p.x != this.x) {
34:          double x = ((p.x - this.x) * ratio) + this.x;
35:          this.y = this.y + (x - this.x) * ((p.y - this.y) / (p.x - this.x));
36:          this.z = this.z + (x - this.x) * ((p.z - this.z) / (p.x - this.x));
37:          this.x = x;
38:        } else if (p.y != this.y) {
39:          double y = ((p.y - this.y) * ratio) + this.y;
40:          this.x = this.x + (y - this.y) * ((p.x - this.x) / (p.y - this.y));
41:          this.z = this.z + (y - this.y) * ((p.z - this.z) / (p.y - this.y));
42:          this.y = y;
43:        } else if (p.z != this.z) {
44:          double z = ((p.z - this.z) * ratio) + this.z;
45:          this.x = this.x + (z - this.z) * ((p.x - this.x) / (p.z - this.z));
46:          this.y = this.y + (z - this.z) * ((p.y - this.y) / (p.z - this.z));
47:          this.z = z;
48:        }
49:      }
50:      public override string ToString() {
51:        return string.Format("{3} {0}, {1}, {2} {4}", this.x.ToString("#0.0"), this.y.ToString("#0.0"), this.z.ToString("#0.0"), '{', '}');
52:      }
53:      public static Point3D add(Point3D p1, Point3D p2) {
54:        Point3D returnValue = new Point3D();
55:        returnValue.x = p1.x + p2.x;
56:        returnValue.y = p1.y + p2.y;
57:        returnValue.z = p1.z + p2.z;
58:        return returnValue;
59:      }
60:      public static Point3D subtract(Point3D p1, Point3D p2) {
61:        Point3D returnValue = new Point3D();
62:        returnValue.x = p1.x - p2.x;
63:        returnValue.y = p1.y - p2.y;
64:        returnValue.z = p1.z - p2.z;
65:        return returnValue;
66:      }
67:      public static Point3D lerp(Point3D p1, Point3D p2) {
68:        return Point3D.lerp(p1, p2, 0.5);
69:      }
70:      public static Point3D lerp(Point3D p1, Point3D p2, double ratio) {
71:        Point3D returnValue = p1;
72:        returnValue.lerp(p2, ratio);
73:        return returnValue;
74:      }
75:      public static Point3D scale(Point3D p, double n) {
76:        Point3D returnValue = p;
77:        returnValue.scale(n);
78:        return returnValue;
79:      }
80:    }
81:  }

Ok, lets review this a piece at a time.  First, we have 3 public properties – x, y, z.  Pretty obvious, they hold our coordinates in 3D space.

Next, we have 2 sets of methods, static methods and public methods.  Yes, they’re redundant – with small classes like this I like to have another set of static methods for ease of use. You don’t have to implement them if you don’t want, or you can just copy and paste.  Either way.

I’ll lightly brush over what these methods do, but the inner workings behind these guys are out of scope of this blog…

Length – Applys only to vectors.  This will measure the distance from {0, 0, 0} to {x, y, z}.  We’ll use this to find our speed.
Add – Applys to both vectors and points.  This simply adds the x1+x2, y1+y2, z1+z2.  We’ll use this to apply our velocity to our current position (along with a few other minor things).
Subtract – Opposite of add.  We won’t actually use this one (I don’t think), but I have it in here for posterity.
Scale – Applys only to vectors.  This one is very handy.  We’ll need this for scaling our speed down to the amount of time between timer calls.  We’ll get into this in a bit.
Lerp – Applys to two points.  Known as Linear Interpolation.  This fun little guy will help us find a point somewhere between the two points provided. I.E. drawing a straight line between p1 & p2, then go (for example) 0.1 percent of the way across that line towards p2.  Where you end up is your answer.
ToString – Obvious I would think – used for debugging.

Particle
Ok, moving on, we’ve got our Particle class.. erum – struct.

1:  using System;
2:  using System.Collections.Generic;
3:  using System.Linq;
4:  using System.Text;
5:  using System.Windows;
6:  using System.Windows.Media;
7:  using System.Windows.Media.Media3D;
8:  namespace ParticleGeneratorControl {
9:    public struct Particle {
10:      private Dictionary _vars;
11:      public Point3D position;
12:      public Point3D velocity;
13:      public UIElement element;
14:      public TimeSpan lifespan;
15:      public TimeSpan age;
16:      public Dictionary vars {
17:        get {
18:          if (this._vars == null)
19:            this._vars = new Dictionary();
20:          return this._vars;
21:        }
22:      }
23:      public bool isAlive {
24:        get {
25:          return this.age < this.lifespan;
26:        }
27:      }
28:      public PlaneProjection GetElement3dProjection() {
29:        PlaneProjection returnValue = (PlaneProjection)this.element.Projection;
30:        if (returnValue == null) {
31:          returnValue = new PlaneProjection();
32:          this.element.Projection = returnValue;
33:        }
34:        return returnValue;
35:      }
36:      public override string ToString() {
37:        StringBuilder returnValue = new StringBuilder();
38:        string format = "{0}: {1}";
39:        returnValue
40:        .AppendFormat(format, "Position", this.position).Append(", ")
41:        .AppendFormat(format, "Vector", this.vector).Append(", ")
42:        .AppendFormat(format, "Speed", this.vector.length.ToString("#0.0")).Append(", ")
43:        .AppendFormat(format, "Age", this.age.TotalSeconds.ToString("#0.0"));
44:        return returnValue.ToString();
45:      }
46:    }
47:  }

So once again, first we have the public properties:
position – a point, the current position of our particle.
velocity – a vector, the speed and direction of our particle.
element – the visual representation of our particle.  Note, for now this will be an ellipse, but later we will be able to make it any UIElement we desire.
lifespan – the amount of time our particle will live for.  This can be infinite, but it is much more typical for this to be a few seconds.
age – the current age of our particle.  Once they get too old, we’ll remove the particle, hide the element and recycle it for later use (this is a very green particle generator – very small carbon footprint).
vars – a dictionary for storing other values that might be of use to someone customizing this control.
isAlive – a readonly property telling us if the age is greater than the lifespan.

I’m going to skip the method description for now.  But before I move on, you’ll notice there are only 2 methods in this class and one of them is the ToString() method.  The reason for this is that the entire lifecycle of this class is handled externally.  This is so that those implementing this class can override the lifecycle functions directly on the ParticleGenerator control without needing to worry about its interaction with other classes.  We’ll get into how this works later.

Particle Generator
And now for the big kahuna: the particle generator class. Add a new Silverlight User Control.  Here’s what the control looks like:

XAML:

 <UserControl
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d"
  x:Class="ParticleGenerator.ParticleGenerator"
  d:DesignWidth="640" d:DesignHeight="480">

Man, that was sort of a let-down huh?  Like I mentioned, everything will be done in C#.  So lets crack open the C# code behind.  First, we’re going to implement a few properties and private fields:

C#:

   public partial class ParticleGenerator : UserControl {
     private Random _random = new Random();
     private Timer _timer;
     private Particle[] _particles;
     private DateTime _lastTick;
     private int _activeParticles = 0;
     public int maxParticles { get; set; }
     public TimeSpan particleLifespan { get; set; }
     public double particleMinSpeed { get; set; }
     public double particleMaxSpeed { get; set; }
     public Point3D particleInitialPosition { get; set; }
     public Point3D particleInitialPositionRadius { get; set; }
     public Point3D particleInitialVelocity { get; set; }
     public double particleInitialVelocityScaleRange { get; set; }
     public double particleInitialVelocityYaw { get; set; }
     public double particleInitialVelocityPitch { get; set; }
     public double particleInitialVelocityRoll { get; set; }

I won’t describe every property and field in here, but the big ones are:
_random – used to make the particle generation randomly distributed.
_timer – which will fire every millisecond and allow us to move the particles.
_particles – the array that will hold all of our particles.
maxParticles – determines the size of the _particles array.  This property can not be changed once the control is initialized.
particleInitialPosition / Radius – properties that determine the position of the particle when first generated.
particleInitialVelocity.
particleInitialVelocity / ScaleRange / Yaw / Pitch / Roll – properties that determine the particles speed and direction upon generation.  The speed will be units per second.

Our control constructor will look like this:

 public ParticleGenerator() {
   InitializeComponent();
   this.maxParticles = 30;
   this.particleLifespan = TimeSpan.FromSeconds(2);
   this.particleInitialPosition = new Point3D() { x = 0, y = 0, z = 0 };
   this.particleInitialPositionRadius = new Point3D() { x = 10, y = 10, z = 10 };
   this.particleInitialVelocity = new Point3D() { x = 0, y = -500, z = 0 };
   this.particleInitialVelocityScaleRange = 0.2;
   this.particleInitialVelocityYaw = 0.5;
   this.particleInitialVelocityPitch = 0.5;
   this.particleInitialVelocityRoll = 0.5;
 }

Basically, we just want to set some reasonable defaults for our values.  We haven’t yet initialized the timer or the particles array because we need to wait for the user’s properties to be set.

 public void init() {
   this._particles = new Particle[this.maxParticles];
   for (int i = 0; i < this.maxParticles; i++) {
     this._particles[i] = this.initParticle();
   }
   this._lastTick = DateTime.Now;
   this._timer = new Timer(this.timerTick, this._particles, 1, 1);
 }

In our init method, we’re going to initialize the array, loop through each item in the array and initialize the particles.  Last, we’re going to set the lastTick property to now (you’ll see why we do this in a minute), and initialize the timer.

Now, lets take a look at that initParticle() method:

 protected virtual Particle initParticle() {
   Particle returnValue = new Particle() {
       element = this.getParticleVisualElement()
     };
   this.LayoutRoot.Children.Add(returnValue.element);
   return returnValue;
 }
 protected virtual UIElement getParticleVisualElement() {
   return new Ellipse() {
       Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)),
       Height = 10,
       Width = 10
     };
 }

All this method is doing is creating a new particle structure, adding the visual element to the control’s Canvas (LayoutRoot), then making sure the particle is hidden.

So, back to the top… remember that timer we initialized?  Lets take a look at what that’s doing…

 this._timer = new Timer(this.timerTick, this._particles, 1, 20)

This timer is set up to call a method called timerTick(object particleArray) every 20 milliseconds and pass in the array of particles.  Now, we can easily update thousands of particles in that time, but this may cause an issue if we’re debugging, as timer ticks are answered by a pool of threads and Visual Studio is no good at handling multi-threaded debugging.

Lets take a look at the timerTick() method:

 private void timerTick(object particleArray) {
   lock (this) {
     Particle[] particles = (Particle[])particleArray;
     TimeSpan deltaTime = this.getTimeSinceLastTick();
     //update all particles
     for (int i = 0; i < particles.Length; i++) {
       if (particles[i].isAlive) {
         particles[i] = this.updateParticle(i, particles[i], deltaTime);
       }
     }
     //draw particles
     this.Dispatcher.BeginInvoke(new UpdateUIDelegate(this.updateUI), particles, deltaTime);
   }
 }

What are we doing here?  The first lock statement prevents race conditions and just general confusion.  The second statement casts the object into an array of particles so we can use the typed instance of it.

Next we allocate a deltaTime variable.  This variable will hold the amount of time it took since the last tick occurred.  Lets see how this is done:

 private TimeSpan getTimeSinceLastTick() {
   TimeSpan returnValue;
   DateTime now = DateTime.Now;
   returnValue = now - this._lastTick;
   this._lastTick = now;
   return returnValue;
 }

Straight forward right? Now minus the time of the last tick equals the time between.  Save now, return time between (a.k.a deltaTime) and we’re done.

Back to our timerTick() method.  Next, we just loop through the array of particles.  For each particle that is alive (age < lifespan) we update the particle.

Ok, so what’s that last BeginInvoke() statement there?  That is simply the statement that will submit a job to the UI thread to update the visual elements of the particles.  Remember, if we’re not in the UI thread, we can’t touch UIElements – you’ll get an InvalidCrossThreadAccess exception.

So let’s dive into the updateUI method.  (By the way, notice it’s using an UpdateUIDelegate?  Normally you can pass function references just by leaving off the parens, but for some reason this wouldn’t work – I had to create a delegate then pass that in… again, not sure why)

 private delegate void UpdateUIDelegate(Particle[] particles, TimeSpan deltaTime);
 private void updateUI(Particle[] particles, TimeSpan deltaTime) {
   int activeParticles = 0;
   //update the particles
   for (int i = 0; i < particles.Length; i++) {
     if (particles[i].isAlive) {
       activeParticles++;
     }
     particles[i] = this.updateElement(i, particles[i], deltaTime);
   }
   this._activeParticles = activeParticles;
 }

Well, the updateUI() method really just loops through the active elements, counting them then calling updateElement() on all the elements.  This is important as we need to update inactive elements as well.  Fairly straight forward really… NEXT!

 public Particle updateElement(int index, Particle particle, TimeSpan deltaTime) {
   Particle returnValue = particle;
   if (returnValue.age >= returnValue.lifespan) {
     //the particle is old, kill off
     returnValue.element.Visibility = Visibility.Collapsed;
   } else {
     returnValue.element.Visibility = Visibility.Visible;
     //update the position
     PlaneProjection projection = returnValue.GetElement3dProjection();
     projection.GlobalOffsetX = returnValue.position.x;
     projection.GlobalOffsetY = returnValue.position.y;
     projection.GlobalOffsetZ = returnValue.position.z;
   }
   return returnValue;
 }
This method is also pretty simple (I do try to keep my methods very simple in case you haven’t noticed)… First we check the age of the particle, if it’s too old we set the element’s visibility = Collapsed and exit out.  If not, we set the visibility to Visible.  Next we get the element’s 3D Projection transformation.  This is the transformation that will allow us to pretend we’re working in 3D space.  The method is pretty simple (you saw it in the Particle code above.  We just take our current position x, y, and z coordinates and assign them to the corresponding GlobalOffset property.  Just for posterity, I’ll quickly review the GetElement3dProjection() method:
 public PlaneProjection GetElement3dProjection() {
   PlaneProjection returnValue = (PlaneProjection)this.element.Projection;
   if (returnValue == null) {
     returnValue = new PlaneProjection();
     this.element.Projection = returnValue;
   }
   return returnValue;
 }
Get the PlaneProjection transform, if it’s null assign a new one then return it.

We’re missing something… what is it?? Ahh, yes, particle generation!  When we’ve first initialized all the particles, they’re hidden.  We want to spit out particles a few at a time, so we’re going to have to make a few updates to some of the methods to accomplish this.  First, we need something to tell us when it’s time:

Private fields:

 #region Particle generation rate
 private int _rateNumberOfParticlesGenerated;
 private Queue _particlesToGenerate = new Queue();
 private TimeSpan _rateTimeSinceLastGenerated;
 private TimeSpan _rateTimeBetweenGeneratedParticles;
 private double _particleRate;
 #endregion

particleRate property:

 public double particleRate {
   get {
     return this._particleRate;
   }
   set {
     this._particleRate = value;
     this._rateTimeBetweenGeneratedParticles = (value > 0) ? TimeSpan.FromSeconds(1 / value) : TimeSpan.Zero;
   }
 }

Because the particleRate is a bit of a complex property, we can’t just use a normal prop { get; set; } to define it.  Anytime it changes, we need to modify all the underlying values.  The real driving factor for how frequently we generate new particles is the _rateTimeBetweenGeneratedParticles field.  This field tells us that we need to generate a new particle every X seconds.  So if the rate is not zero, we’ll set that field to 1/value seconds.  I.E. if the particleRate is set to 3 particles per second, we want to genarate a new particle every 1/3rd second.

 private int newParticlesToGenerate(TimeSpan deltaTime) {
   int returnValue = 0;
   this._rateTimeSinceLastGenerated += deltaTime;
   while (this._rateTimeSinceLastGenerated > this._rateTimeBetweenGeneratedParticles) {
     this._rateTimeSinceLastGenerated -= this._rateTimeBetweenGeneratedParticles;
     returnValue++;
   }
   return returnValue;
 }

The newParticlesToGenerate() method returns the number of new particles to generate.  It figures this out by calculating the amount of time since the last particle was generated, and while that time is greater than the timeBetweenGeneratedParticles (calculated above in the particleRate setter) we add a new particle to generate and subtract the timeBetween from the timeSince.

Now that we’ve gotten that all squared away, we just need to call that from the timerTick() method:

 private void timerTick(object particleArray) {
   lock (this) {
     Particle[] particles = (Particle[])particleArray;
     TimeSpan deltaTime = this.getTimeSinceLastTick();
     //generate new particles
     int newParticles = this.newParticlesToGenerate(deltaTime);
     for (int i = 0; i < newParticles; i++) {
       if (this._particlesToGenerate.Count > 0) {
         int index = this._particlesToGenerate.Dequeue();
         particles[index] = this.generateParticle(particles[index]);
       }
     }
     //update all particles
     for (int i = 0; i < particles.Length; i++) {
       if (particles[i].isAlive) {
         particles[i] = this.updateParticle(i, particles[i], deltaTime);
         //If no longer alive, add to list of reusable particles
         if (!particles[i].isAlive) {
           this._particlesToGenerate.Enqueue(i);
         }
       }
     }
     //draw particles
     this.Dispatcher.BeginInvoke(new UpdateUIDelegate(this.updateUI), particles, deltaTime);
   }
 }

Notice the new code here.  Before we dive down the particleGeneration rat hole, lets look at the second change, with the comment “If no longer alive…”.  if the particle.isAlive property returns false after the updateParticle() call, that method must have caused the particle to age over it’s lifespan, so this should be the first time we’ve seen this particle croak, so we’re going to enqueue it in the _particlesToGenerate queue.

Ok, so back to the first change with the comment “Generate new particles”.  First, we get the number of new particles to generate, then just loop the number of times provided by the return value, grab the next available particle from the _particlesToGenerate queue (if there is one) and call generateParticle():

 protected virtual Particle generateParticle(Particle particle) {
   Particle returnValue = this.resetParticle(particle);
   this._rateNumberOfParticlesGenerated++;
   return returnValue;
 }
private Particle resetParticle(Particle particle) {
    particle.position = this.getNewParticlePosition();
    particle.velocity = this.getNewParticleVelocity();
    particle.lifespan = this.particleLifespan;
    particle.age = TimeSpan.Zero;
    return particle;
}
private Point3D getNewParticlePosition() {
    Point3D returnValue = new Point3D();
    returnValue.x = this.particleInitialPosition.x + (this.plusOrMinus() * this.particleInitialPositionRadius.x * this._random.NextDouble());
    returnValue.y = this.particleInitialPosition.y + (this.plusOrMinus() * this.particleInitialPositionRadius.y * this._random.NextDouble());
    returnValue.z = this.particleInitialPosition.z + (this.plusOrMinus() * this.particleInitialPositionRadius.z * this._random.NextDouble());
    return returnValue;
}
Please note, if any of you purists want to call me out on the fact that the initialPositionRadius calculation here is not a true radius, don’t, its just a simplification on my part (both in naming and calculation).
 private Point3D getNewParticleVelocity() {
   Point3D returnValue = this.particleInitialVelocity;
   returnValue.scale(1 + this.plusOrMinus() * this.particleInitialVelocityScaleRange * this._random.NextDouble());
   double yaw = this.particleInitialVelocityYaw * this._random.NextDouble();
   double pitch = this.particleInitialVelocityPitch * this._random.NextDouble();
   double roll = this.particleInitialVelocityRoll * this._random.NextDouble();
   returnValue = MatrixGeometry.transform(returnValue, yaw, pitch, roll, 0, 0, 0);
   return returnValue;
 }
 private int plusOrMinus() {
   if (this._random.NextDouble() > 0.5) {
     return 1;
   } else {
     return -1;
   }
 }
Almost forgot about the last supporting class: MatrixGeometry
 using System;
 using System.Windows.Media.Media3D;
 namespace ParticleGenerator {
   public class MatrixGeometry {
     public static Matrix3D YawPitchRollMatrix(double yaw, double pitch, double roll) {
       return MatrixGeometry.TransformMatrix(yaw, pitch, roll, 0, 0, 0);
     }
     public static Matrix3D TranslationMatrix(double x, double y, double z) {
       return new Matrix3D() { OffsetX = x, OffsetY = y, OffsetZ = z };
     }
     public static Matrix3D TransformMatrix(double yaw, double pitch, double roll, double x, double y, double z) {
       Matrix3D returnValue;
       //Math translations: yaw = a, pitch = b, roll = y
       //Common calculations
       double cosA = Math.Cos(yaw);
       double cosB = Math.Cos(pitch);
       double cosY = Math.Cos(roll);
       double sinA = Math.Sin(yaw);
       double sinB = Math.Sin(pitch);
       double sinY = Math.Sin(roll);
       //matrix elements
       double m11 = cosA * cosB;
       double m12 = sinA * cosB;
       double m13 = -sinB;
       double m14 = 0;
       double m21 = cosA * sinB * sinY - sinA * cosY;
       double m22 = sinA * sinB * sinY + cosA * cosY;
       double m23 = cosB * sinY;
       double m24 = 0;
       double m31 = cosA * sinB * cosY + sinA * sinY;
       double m32 = sinA * sinB * cosY - cosA * sinY;
       double m33 = cosB * cosY;
       double m34 = 0;
       double m41 = x;
       double m42 = y;
       double m43 = z;
       double m44 = 1;
       returnValue = new Matrix3D(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
       return returnValue;
     }
     public static Point3D transform(Point3D point, Matrix3D matrix) {
       Point3D returnValue = point;
       returnValue.x = point.x * matrix.M11 + point.y * matrix.M21 + point.z * matrix.M31 + matrix.OffsetX;
       returnValue.y = point.x * matrix.M12 + point.y * matrix.M22 + point.z * matrix.M32 + matrix.OffsetY;
       returnValue.z = point.x * matrix.M13 + point.y * matrix.M23 + point.z * matrix.M33 + matrix.OffsetZ;
       return returnValue;
     }
     public static Point3D transform(Point3D point, double yaw, double pitch, double roll, double x, double y, double z) {
       return MatrixGeometry.transform(point, MatrixGeometry.TransformMatrix(yaw, pitch, roll, x, y, z));
     }
   }
 }
And this one I’ll leave completely unexplained for now.  If you’d like to read up on the math behind this class, there’s a ton of information out there, but this is the best I’ve found so far:
http://planning.cs.uiuc.edu/node96.html Thank you Steven LaValle.
Suffice to say, yaw, pitch and roll are terms used to describe angle transformations on vectors.  Typically described in radians, they measure the rotation to apply to a vector in each given plane.  http://en.wikipedia.org/wiki/Flight_dynamics read up for more info.
And finally, we need to enqueue all of the particles into the _particlesToGenerate queue when we first initialize them:
 public void init() {
   this._particles = new Particle[this.maxParticles];
   for (int i = 0; i < this.maxParticles; i++) {
   this._particles[i] = this.initParticle();
   this._particlesToGenerate.Enqueue(i);
 }
 ...

Debugging

The final step in all of this is to get it to run.  You’ll notice that you can’t just click the run button because we can’t execute a class library.  So lets go ahead and get something we can debug.
Right click your solution in the Solution Explorer and click Add > New Project…
Select the Silverlight Application and name the new project.  I chose “ParticleGeneratorTest”.  I know, I’ve got a way with naming things…
Clicking OK will prompt Visual Studio to ask you if you want to host your new application in a web project.  Click OK.
Right click the References folder under your new Silverlight application and click Add Reference…
Under the Projects tab chose ParticleGenerator.
Your MainPage.xaml file should already be open, if not, open it now.  Expand your Toolbox toolbar and you should see your new ParticleGenerator control.  Click and drag it onto the canvas.  Your new XAML should look like this:
 <UserControl x:Class="ParticleGeneratorTest.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 mc:Ignorable="d"
 d:DesignHeight="300" d:DesignWidth="400"
 xmlns:my="clr-namespace:ParticleGenerator;assembly=ParticleGenerator">
Change some of the properties here so that your control stretches across the entire grid:
Margin=”0,0,0,0″ HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch”
Now, unfortunately, those properties we set up aren’t really the easiest to manipulate in the editor.  We can fix this later, but for now we’ll need to set them manually through the XAML:
 <my:ParticleGenerator particleRate="50" maxParticles="100"
 Name="particleGenerator1" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
Last thing.  We need to call that pesky init() function to get things started, so open up the MainPage.xaml.cs and plug it in:
 public MainPage() {  
   InitializeComponent();  
   this.particleGenerator1.init();  
 }  

Now lets fire up that bad Larry and see what we’ve got!

Damn, that was a lot.  If you’re still with me, congratulations, you’ve now got a very cool particle generator.  This project will form the basis for Part 2 (which will hopefully be much much shorter).

Download the full project here