When you write games in silverlight you are going to want to make a custom mouse cursor. Maybe you want a gun cross hair or maybe an animated cursor of some sort. I’ve found no way to do this other than to turn off the cursor and hook an image up to the mouse move events.
Basically let’s start with a silverlight application and change the Grid to a Canvas like this:
<UserControl x:Class="MouseCursorReplacement.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:DesignWidth="640" d:DesignHeight="480">
<Canvas x:Name="LayoutRoot">
</Canvas>
</UserControl>
Now add a cursor representation as an image tag and point it to your new cursor file. In this case I’m using a cross hair. I make the ZIndex high so it floats on top of anything I put in.
<UserControl x:Class="MouseCursorReplacement.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:DesignWidth="640" d:DesignHeight="480">
<Canvas x:Name="LayoutRoot">
<Image x:Name="CustomCursorImage" Source="cross.png" Canvas.ZIndex="100"/>
</Canvas>
</UserControl>
Now go into your code behind and setup a load event and disable the cursor:
public partial class MainPage : UserControl
{
public MainPage()
{
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
InitializeComponent();
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this.Cursor = Cursors.None;
}
}
Now add a mouse move event and finally the code that will make the image move around as your new cursor.
public MainPage()
{
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
this.MouseMove += new MouseEventHandler(MainPage_MouseMove);
InitializeComponent();
}
void MainPage_MouseMove(object sender, MouseEventArgs e)
{
Point position = e.GetPosition(LayoutRoot);
double leftOffset = CustomCursorImage.ActualWidth / 2;
double topOffset = CustomCursorImage.ActualHeight / 2;
double newLeft = position.X - leftOffset;
double newTop = position.Y - topOffset;
Canvas.SetLeft(CustomCursorImage, newLeft);
Canvas.SetTop(CustomCursorImage, newTop);
}
The last part. And I find this a little ‘magical’ is that when the background was white the mouse kept “losing” the new cursor. So I changed the background to classic ‘directx’ cornflowerblue and the problem went away (I don’t know why and believe me I don’t usually fall for the ‘it must be magic’ comment, but apparently it works?):
<UserControl x:Class="MouseCursorReplacement.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:DesignWidth="640" d:DesignHeight="480">
<Canvas x:Name="LayoutRoot" Background="CornflowerBlue">
<Image x:Name="CustomCursorImage" Source="cross.png" Canvas.ZIndex="100"/>
</Canvas>
</UserControl>