How do I "Stick" a shape to the mouse in WPF? - c#

I have a wpf application that has some shapes on a canvas I want to allow the user to click on a shape and then the shape gets stuck the the mouse until they click again.
So far I know very little about WPF so go easy on me ;)

Hopefully this is what you're looking for.
"Mouse dragging logic is fairly straightforward: In the OnMouseDown handler, you save the position of both the object you want to drag and the mouse pointer, and you call CaptureMouse. In OnMouseMove, you calculate the difference between the coordinates of the current mouse pointer position and the saved position, and add that to the original object position. (If you're on a Canvas, you can move the object by calling Canvas.SetLeft and Canvas.SetTop for the object; otherwise you can adjust a TranslateTransform object set to the object's RenderTransform property.) In OnMouseUp, you call ReleaseCapture.
Because your app can lose the mouse capture in other ways (such as the appearance of a system modal message box), you'll also want to override OnLostMouseCapture to abort the dragging operation (if it hasn't terminated with OnMouseUp) and perform cleanup. You might also want to override OnTextInput to abort the drag if the user presses the Escape key."
Copied from http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b6c51eef-269e-4c85-96af-b5b1e4cb9bd5/ there's also code up on this site for how to do it.

Check out this Thread - http://silverlight.net/forums/t/68889.aspx
Since your 'Stick' is on the Canvas, keep setting the Canvas.Left and Canvas.Top on MouseMove with MousePositions

Related

Change pointer cursor when hovering over map elements

My UWP application contains a map with several POI. I am trying to change the mouse cursor from an arrow to a hand when hovering over specific poi to indicate its clickable.
This would change the cursor as soon as it enters the map still, as a simple test, I added a PointerEntered event for the mapcontrol and within it I have the following to change the cursor:
Window.Current.CoreWindow.PointerCursor = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.Hand, 0);
It appears though the cursor does change however immediately gets overridden back to the pointer cursor.
Edit: Just realised When a poi is clicked (i.e. is selected) the cursor changes to a hand even when not over the map control until the poi is unselected. No good as I would like the cursor to change dynamically when hovering over a poi and revert back to cursor when moved away.
Change pointer cursor when hovering over map elements
I'm afraid you can't edit the default cursor for map element, Because it has handled internally, it will not fired, even you has listen PointerEntered event, it consumed by the control and not passed up the control chain. If you do want this feature, the better way is post this feature with windows feed backhub app.
I don't know if it works just like WinForms, I had to do something like this to click on labels (couldn't use link-labels), what I used was in the Mouse_Move event of the label and it was basically
if (Cursor.Current == Cursors.Default)
{
Cursor.Current = Cursors.Hand;
}
and similar changes and behaviors due to the various conditions. This however got me a small issue: this statement changes the mouse graphic anytime you move on the control, but personally on Windows settings I use the trail graphic function for the mouse (leaving a trail of pointers whenever I move the mouse on the screen), what I suggested you disables this function, or better, it conceals it, since it "recreates" the mouse graphic for every move you do onto the control, and thus it "undoes" the graphic for the mouse and recreates it as a Hand (in my instance). If it doesn't concern you though, it works just fine.
Just I repeat myself: I use this on WinForms, but since it's C# I suppose it just will work(?)

WPF: Keep custom cursor while mouse is down

I have created a custom cursor and applied it to my control via the Cursor property and it displays correctly while the mouse is over the control, however once I click, the cursor changes back to default. What I would like is the custom cursor to be persisted while the mouse is down (and potentially being moved) and return to normal whenever the mouse comes up (over any possible control). I realize I could do this by setting the Mouse.OverrideCursor on mouse down, but I'm not sure how I would set the override cursor back when the mouse comes up because it could be released anywhere on the screen. The behavior I want is similar to clicking in a cell and dragging in Excel. Does anyone have any suggestions for how I can implement this behavior?
Edit:
I tried following the advice in this answer: https://stackoverflow.com/a/2986757/3818295 however my PreviewMouseLeftButtonUp handler never gets invoked.
If you want to change the cursor globally for your entire application, then use the Mouse.SetCursor method. The cursor will remain changed until you explicitly change it again. To change it back, call Mouse.SetCursor(Cursors.Arrow); don't pass in null or Cursors.None, as those will give you a special 'invisible' cursor.
If you want to change the cursor only while the mouse is down, then the control that initiated the 'drag' operation will need to capture the mouse so that it continues to receive events even after the cursor leaves the original control. This ensures the source control eventually receives the mouse up event (unless the capture is lost). To capture the mouse, call either c.CaptureMouse() or Mouse.Capture(c), where c is your control. You will need to release the capture when the drag operation terminates, e.g., via c.ReleaseCapture().
It would be a good idea to temporarily subscribe to the drag source's LostMouseCapture event for the duration of the drag, and cancel the drag operation if capture is lost. If capture is lost, you aren't guaranteed to receive the mouse up event, so at that point you should just give up. Remember to unsubscribe from LostMouseCapture after the drag terminates.

Getting mouse coordinates relative to target control in drag/drop operations

I see how to get the coordinates of the mouse relative to the entire screen when doing Drag & Drop events, but I'm a bit unclear on the best way to get the mouse coordinates relative to the control the drop occurs in. Do I have to calculate it based on the controls position in the form and the form's position in the screen or is there a more straightforward way of doing it?
You can use Control.PointToClient method:
yourTargetControl.PointToClient(screenPoint);

WPF - Is it possible to (programmatically) disable multi-touch?

I have a problem with WPF application/presentation for Tablet PC with (multi-) touch screen. One "slide" of the presentation consists of Canvas on background and of a small UserControl. This UserControl is invisible at start, but whenever user touches the screen, it becomes visible and if user moves his finger, the control moves accordingly ("following" the finger, like a cursor). Then, when user stops touching the screen, the control becomes invisible again.
This is not very hard to do using the TouchDown, TouchUp and TouchMove event handlers and it works fine if user touches the screen with just one finger. However, when user holds one finger on position X (e.g. canvas coordinates [100,100]) and another finger on position Y (e.g. [500, 100]), the UserControl starts jumping between positions X and Y, which doesn't look very well...
Now I'd like the screen to react only to one touch at the time, which I can do in operating system (Windows 7) using Control Panel -> Pen and Touch -> Touch by unchecking item "Enable multi-touch gestures and inking".
This works fine, exactly as I want it to, unfortunately it's not very convenient, because sometimes I need to use the multi-touch and I can't change it every time I decide to use the application...
That's why I'd like to ask if there is any way how to disable the multi-touch programmaticaly, in the application (or just in WPF UserControl) where I need it. Thanks a lot in advance for any help.
Take a look at the TouchDevice.Id property. You can get this from the event arguments passed to the touch events and it will allow you to uniquely identify the touch events so that you don't confuse the first touch with subsequent parallel touches.
You can convert the C++ code from the following question to C#: Programatically enable / disable multitouch finger input?
The CodeProject article, "Single App Instance in C#: Yet Another Way" has a C# implementation of the Win32 GlobalAddAtom() function and PInvoke.net has a reference page for SetProp().
You can use a boolean eg. IsCurrentTouched, set it true if user touches and the control is shown, and set it back to false when the touch is released.
While IsCurrentTouched is true don't react to other touches. So you are able to use multitouch only when needed ;-)

How can I develop scale like measure it add on in Firefox

I want measuring tool in project that will be same as measure it in Firefox (add-on). How to do this?
To get such a think to work you'll need an application that runs as a tray icon or something like that. Then you open your application and tell him, that you'd like to measure.
Now, you'll go and put a transparent window onto the whole screen(s) and wait for a mouse move event. Within the mouse move event, you'll check the mouse button state. If it is going to be hit you know the starting position and you can draw some kind of user-control at this position and if the user releases the mouse button, you're going to stop the resizing of your user-control.
The user-control itself should be semi-transparent and checking for the resizing and/or paint events, to draw the ruler lines around the border.
Last but not least you can show some kind of tooltip or labelcontrol in relation to the position and size of your user-control and screen bounds to give some status informations.
To get a good starting point about how to get the transparent overlay part done, you can take a look into ObjectListView Overlay.
--EDIT--
One solution could be:
Create a separate transparent windows form
Upon certain key press, for instance Ctrl+Shift+R, show your app with lower transparency level; so that user can see the background.
Draw ruler upon form load
You may allow user to move the ruler window with mouse click.

Categories