Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating cursor without using WinForms

Is it possible to rotate FrameworkElement.Cursor?

My application allows user to rotate objects around their center. Once rotated, default resize cursors appear awkward on top of tilted borders.

Mouse cursor not affected by transform

My first thought was to apply RotateTransform to the Cursor property, but it looks like we can't do that in XAML. Next I tried inheriting from Cursor class, but it looks like MS guys have sealed it.

Another way is to set default cursor to None and use my own image (with transform) and set its position upon MouseMove. I'm not willing to go down that path if there are easier alternatives. Anyone with a good suggestion?

I'm looking for a WPF-only solution if at all possible.

like image 713
dotNET Avatar asked Aug 24 '16 12:08

dotNET


1 Answers

Finally managed it within the bounds of WPF, without using WinForms or PInvokes. Instead of creating custom cursors (*.cur) on the fly or converting Visuals into cursors, I used MouseMove event of the parent control along with a WPF element (Path) as my cursor. Here's the way just in case anyone is interesed:

  1. Set the Cursor of your resize thumb (or whatever you're using as the border of your shape) to None, so that WPF doesn't display default arrow.
  2. Create your own cursor. Could be any FrameworkElement, but I have used Path for its easy manipulation to create any shape you want. Note that most of the properties I have set below are important.

    <Path x:Name="PART_EW" Data="M0,20 L25,0 25,15 75,15 75,0 100,20 75,40 75,25 25,25 25,40z" Fill="White" Stroke="Black" StrokeThickness="1" Visibility="Collapsed" Width="50" Height="20" Opacity=".7" Stretch="Fill" Panel.ZIndex="100001" HorizontalAlignment="Left" VerticalAlignment="Top" IsHitTestVisible="False" />

Add the following code in your resize thumb:

protected override void OnMouseEnter(MouseEventArgs e)
{
  base.OnMouseEnter(e);

  var Pos = e.GetPosition(this);
  PART_EW.Margin = new Thickness(
                       Pos.X - PART_EW.Width / 2, 
                       Pos.Y - PART_EW.Height / 2, 
                       -PART_EW.Width, 
                       -PART_EW.Height);
  PART_EW.Visibility = Visibility.Visible;
}

protected override void OnMouseLeave(MouseEventArgs e)
{
  base.OnMouseLeave(e);
  PART_EW.Visibility = Visibility.Collapsed;
}

protected override void OnMouseMove(MouseEventArgs e)
{
  base.OnMouseMove(e);

  var Pos = e.GetPosition(designerItem);
  PART_EW.Margin = new Thickness(
                       Pos.X - PART_EW.Width / 2, 
                       Pos.Y - PART_EW.Height / 2, 
                       -PART_EW.Width, 
                       -PART_EW.Height);
}

Note that I've not set RotateTransform of my Path anywhere in the code, since it is already part of the resize thumb and therefore acquires the angle of the parent control automatically.

Hope this helps people down the road.

like image 113
dotNET Avatar answered Oct 17 '22 23:10

dotNET