Custom Cursors in Silverlight

There has been quite a few blog posts on how to create custom cursors in Silverlight, but I felt some of them were very limited or not very re-useable, or required you to put the cursor in the layout and put restrictions on your layout (like for instance requiring you to use a Canvas as parent for your cursor). So I ended up writing my own class for it that doesn’t have any of these restrictions.

The basic idea is the same as other approaches out there: You “disable” the cursor on your element by setting myElement.Cursor = Cursors.None. Next you move a custom UIElement around on top of your layout which represents your custom cursor. My approach uses a Popup, and therefore never requires you to modify your layout, and you can easily change the cursor on the fly. The cursor look is defined using a DataTemplate and can contain animations and so on.

All you need to do is define a DataTemplate and use the Attached Property to define the template. Below is an example of this working on a border element:

<UserControl x:Class="CustomCursor.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:SharpGIS.CustomCursor">
   <UserControl.Resources>
        <DataTemplate x:Key="CircleCursor">
            <Ellipse Fill="Red" Width="20" Height="20" />
        </DataTemplate>
   </UserControl.Resources>
   <Grid>
       <Border Background="Blue" 
           local:CustomCursor.CursorTemplate="{StaticResource CircleCursor}" />
   </Grid>
</UserControl>

And that’s all there is to it!

If you need to customize where the centering of the element is, simply apply a TranslateTranform to the element. Ie. if you want the above circle to center on the mouse location, add a TranslateTransform of –10,-10 to the ellipse.

Get Microsoft Silverlight

Downloads:

Update: Someone awesome ported this to Windows Store apps as well! Go download here: http://customcursor.codeplex.com/

Comments (9) -

  • Thanks for this Morten!  
    Would it be possible to add an example using an image for the cursor?
    I've tried with an Image control and also a Rectangle with ImageBrush fill..  in both instances I get "Element is already the child of another element"
  • Dave A-W:
    It should just be a matter of putting an image in the DataTemplate:
    <UserControl.Resources>
            <DataTemplate x:Key="CircleCursor">
                <Image Width="20" Height="20" Source="/MyCursorImage.png" />
            </DataTemplate>
    </UserControl.Resources>

    What did you do to make that error happen? I would like to see if I can repro it
  • Great post. Tried it now with Image. Hoped the guys in Redmond will do that and not us a workaround.
  • Oren: Actually I like it better this way. I don't see why Microsoft needs to do any more. No matter what they do, there's going to be something missing. This is simple and flexible, and with this approach easily re-useable.
  • Thanks for posting this Morten.

    I'd like to use this strategy in the ArcGIS Viewer for Silverlight.  I guess this means I need to assign the attached property in the code behind.  Is this possible?
  • Kirk: ANYTHING you can do in XAML you can do in code-behind
  • I like this a lot. I had to translate to VB, but have it working.
    I was able to use some of the Path-Data geometry from the sample symbols on the esri resource center to create new cursors. I made a lightning bolt cursor.
  • Hi Morten,

    I've compiled your project and am using the DLL in a test mapping project (the ESRI Silverlight API, of course).  It works fine, but it sure does spike the CPU on continuous mouse movements.  It's a full page Map control, so that probably has something to do with it, but I don't think that would be uncommon in this sort of project.

    Lance
  • I have a similar problem.  The CPU doesn't spike but the custom cursor movement lags behind the standard cursor.  The custom cursor appears to always be chasing the main one.  Looks weird.  If no Silverlight panels are open performance is much better.

Add comment