I am trying to construct some SVG shapes which should be resize-able along one or more edges.
The way I do this is by creating an additional shape on top of the shape which I want to be able to resize. I use this shape to indicate to the user that an edge can be clicked on and dragged. This shape tends to be a line that lights up once the user moves their mouse over it and I change it's position while resizing the main shape.
Using a combination of the mousedown, mousemove and mouseup events, I get the mouse's current position and adjust the shape accordingly.
All seems to work. However, what I can't seem to figure out is that should I move my mouse a little bit too quickly, while dragging the edge, it seems as though the mouse looses track of the event and the dragging of the edge fails. At this point I am have to find the edge again and restart the process.
Any idea how to either stop the mouse from losing the edge while dragging? Or perhaps slow down the event so as not to allow the mouse to jerk into any one direction too fast?
I have created a a sandbox here to demonstrate the issue.
Related
I have a WPF app with a canvas inside a ScrollViewer. On the canvas I have some rectangles that I drag along a timeline (left-right). This works fine with a mouse, but on a touch screen I get weird behavior if the canvas is wider than the main form. First, when you begin to drag the rectangle, the canvas pans until it has scrolled to the limit, then the rectangle starts to move. I doesn't do this when using a mouse.
Another strange this is that if I pan/drag the canvas (using touch) to the limit of the scrollviewer, the main form compresses by 20-50 pixels on the side opposite of the pan direction. It springs back to shape as soon as you stop dragging. What's going on here and how do I disable this?
It seems that this has to do with ManipulationBoundaryFeedback, but I don't understand exactly how...
EDIT:
So I was able to get a little further by setting the scrollviewer panningmode to PanningMode.None in the rectangle TouchDown handler and then setting it back to PanningMode.Both in the TouchUp handler. This solved the problem of the canvas panning to the limit before the rectangle would move.
Well, I finally got my app to work with touch. As I mentioned above, setting the PanningMode to None on the TouchDown event eliminated the problem with the ScrollViewer. Setting it back to Both in the TouchUp event re-enabled it. What this means is that I can't drag the rectangle past the point where the ScrollViewer would start panning, but in my case this was not a problem.
I also had some issues with the MouseLeftButtonDown event firing during the TouchMove event so I removed it during TouchDown
-= new MouseButtonEventHandler(drag_start)
and re-added it back during TouchUp to eliminate the glitchy behavior.
+= new MouseButtonEventHandler(drag_start)
Maybe this will help someone in the future...
I have created a usercontrol that is essentially a text editor (using Graphics.Drawstring in OnPaint).
I have set AutoScroll = true, and AutoScrollMinSize values appropriately. Everything is working how it should...
EXCEPT, i would like the control to scroll itself WHILST I am currently scrolling (i.e. click and drag the scroll bar... and whilst it is being dragged the control should be scrolling the entire time). At the moment it only scrolls when the scroll bar is released (mouse up).
I have tried implementing _Scroll and invalidating the control, but that just makes it flicker uncontrollably.
I cannot find any examples online for this, due to it being difficult to describe!
Can anyone point me in the right direction please?
Control.Invalidate() will make something flicker badly. I faced this problem drawing cross-hairs over a mouse position on a PictureBox drawing a line chart before. The trick is to use (and I cant remember which one is best to come first)
Control.Update();
Control.Refresh();
in the Scroll event. Depending on what else you are drawing in the Control and how you are drawing it this may be better for you. Also this is tested on PictureBox, Control may be another matter.
Is there any simple way to move picture parts (any stuff created with DrawImage or DrawString)?
My smart idea:
Override DrawImage(DrawString) method adding ability to store width, height, left, top, of drawn image (and may be boolean variable 'sizable' if I use DrawImage method) to a list of objects. Attach function "WhatToMove" to PictureBox's MouseMove event, which walks through a list of stored rectangle objects, detects what rectangle cursor is over, in case of resizeable rectangle detect if cursor is over any of rectangle's borders and pass this stuff as parameters to the MouseDown function, when I click. Then MouseDown function will attach new function "MoverResizer" to MouseMove event, which redraws picture box with moved or resized parts of image, updates proper rectangle object in list, and also detachs "WhatToMove" from MouseMove. On MouseUp and Leave events of PictureBox detach "MoverResizer" and attach "WhatToMove".
If you think this idea can live you will really help me if tell me how to override DrawImage.
My dumb idea:
Create Labels without text and with borders and locate them over PictureBox right over proper image parts. Then make them draggable and sizeable with their own events. Then translate positions of labels to positions of parts of picture and redraw picturebox. This is simply but I think not so perfect as method above.
I'm trying to write a WinForms program that will capture mouse coordinates upon pressing and (more importantly) releasing the middle mouse button.
My form has topmost set to true (so that text in it can always be visible even when it doesn't have focus).
What I'm aiming for is being able to hover the mouse over a game window after my program starts, hit the middle mouse button, and have it record the mouse position for later use.
I can get it to detect when the middle mouse button is clicked inside the form using the MouseUp event (bound to the form itself) but have no clue what I need to do to have it detect when the mid mouse is clicked outside my form.
Thanks for any help guys.
I believe what you are after are called low level hooks. A quick google brings up this: Erroneous Mouse Coordinates Returned from Low Level Mouse Hook C#
A microsoft example of how to do can be found here: http://support.microsoft.com/kb/318804
I'm trying to modify the default graph viewer of the Graph# library because its user interface is awful (just try dragging a node outside of the boundaries, you'll see!)
The basic setup is this: there is a GraphCanvas control (inherited from Panel) which has children of Vertex and Edge control types. What I want to achieve is:
GraphCanvas has scroll bars if the contents do not fit in the screen;
GraphCanvas can also be scrolled by "dragging" it (just click on an empty space and drag);
GraphCanvas can be zoomed in and out (via CTRL+mouse wheel);
Vertices can be dragged around. If a vertex is dragged outside the current boundaries of GraphCanvas, the boundaries are increased. The scroll bars should reflect this, however the current viewport should not scroll away while the vertex is being dragged . The same goes if dragging a vertex reduces the boundaries of GraphCanvas - it should stay the same size until the drag operation is finished and resize only then. Automatically scrolling the viewport during a drag operation is awfully confusing and easily introduces dragging errors. See the original implementation if you want to know what I mean.
Although I've got a fair bit of experience with .NET, I'm still a complete beginner in WPF. My current attempt is (in the measure/arrange layout phase) to give each vertext the XY coordinate it desires (even if negative) and implement zooming/scrolling by handling mouse events on the GraphCanvas and modifying the RenderTransform property. Dragging just changes the XY coordinates on the specific vertex (probably triggering the re-layout of the whole thing which would be nice to avoid too). Scrollbars are implemented by placing the GraphCanvas inside a ScrollViewer and implementing IScrollInfo on the GraphCanvas.
Unfortunately there seems to be a problem: I can get mouse events on the GraphCanvas itself only if it has a background at the point. That would be OK, I want a white background anyway, but in the negative coordinates of the GraphCanvas it does not draw the background - and thus does not respond to mouse events.
I'm also wondering if I'm doing the Right Thing by allowing all my child controls (vertices and edges) to go into negative coordinates. How would you implement this?
Added: To clarify about the background problem check out the following screenshot:
(source: valts.21.lv)
What you see here is a simple Windows Forms form with a WPF Host control on it. That has a ScrollViewer in it, and the ScrollViewer has the GraphCanvas in it. The GraphCanvas contains 4 vertices and 6 edges.
The GraphCanvas is stretched to fill the ScrollViewer. But since some of the vertices are at negative coordinates, it has a RenderTransform applied which simply shifts everything to the right (TranslateTransform). It also has a white background brush.
Note the gray area on the left. That's still a part of the GraphCanvas, but the background brush somehow doesn't exted there. Also, if I left-click there with my mouse (not on a node, but on the gray area), I do NOT get an event. If I left-click on the white area, I get all events just fine.
Call CaptureMouse on canvas.mouseDown and ReleaseMouseCapture on mouse up. Also, if you set your canvas background to transparent it will still be hit testable
You can attach a 'Draggable' behavior to each element.