How do I go about implementing drag delta on shapes - wpf

How do I go about implementing the drag delta on a Shape, I have the following code:
void Connector_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.ClickCount == 1)
{
this.Focus();
this.CaptureMouse();
this.RaiseEvent(new DragStartedEventArgs(0,0));
initMousePoint = e.GetPosition(this);
}
e.Handled = true;
}
void Shape2_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
currMousePoint = e.GetPosition(this);
if (this.IsMouseCaptured)
{
this.RaiseEvent(new DragDeltaEventArgs(0,0);
}
}
void Shape2_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
this.ReleaseMouseCapture();
}
Now for the DragDeltaEvent args do I need to compute the drag in the mousemove and pass it to the event, also is this the right way to raise the event. If this works, then I should only subscribe to the drag delta event and use it as a thumb? Note, I do not want to template the thumb with the shape, providing this answer won't help me.
note the chagnes, about the getting the position of the mouse, this I don't think works, because it gets the position relative to the element, not the containing panel, so I don't think i will be able to find the drag distance this way.

I solved it using:
currMousePoint = e.GetPosition(this);
double dragHorizontal = currMousePoint.X - initMousePoint.X;
double dragVertical = currMousePoint.Y - initMousePoint.Y;
//Set the new canvas top and left proeprties here.

Related

WPF add button/image to where i click

Just wanted to know if its possible to do it like winform? Where i can add a button to where i last click. I tried googling but dont think i found anything similar. Will the grid for WPF be an issue where i can place my button freely on click?
Idea is to click on the coordinate and then press the button to add an image/button.
Below is what i did so far, havent added the button function yet, just wanted to know if its possible to do it as i have done so for winform before.
public MainWindow()
{
InitializeComponent();
MainWindow.xCoord = -1;
MainWindow.yCoord = -1;
}
private void AddEvent_Click(object sender, EventArgs e)
{
if (MainWindow.xCoord < 0 || MainWindow.yCoord < 0)
{
MessageBox.Show("Please select a coordinate");
return;
}
}
public void MainWindow_Mouseup(object sender, MouseEventArgs e)
{
Point p = e.GetPosition(this);
textBox1.Text = "x-" + p.X + "y- " + p.Y;
MainWindow.xCoord = (int)p.X;
MainWindow.yCoord = (int)p.Y;
}
Yes you can do it, and you would need to use a Canvas to draw the button. This can be contained inside the Grid, but AFAIK the Canvas is the only way to have a sort of "Draw" function with UI Controls.
You will want to capture the MouseUp event within the Canvas and then add your button at the location you can retrieve in the Handler.
XAML:
<Grid>
<Canvas x:Name="ButtonCanvas" MouseUp="ButtonCanvas_MouseUp"/>
</Grid>
Code Behind:
private void ButtonCanvas_MouseUp(object sender, MouseButtonEventArgs e)
{
Point p = e.GetPosition(ButtonCanvas);
textBox1.Text = "x-" + p.X + "y- " + p.Y;
MainWindow.xCoord = (int)p.X;
MainWindow.yCoord = (int)p.Y;
}
Then just have a function that will create and add a Button at these coordinates (I will assume you have some sort of "Add Button to Canvas" Button):
private void AddButtonToCoord_Click(object sender, EventArgs e)
{
var button = new Button();
//--change button properties if you want--
//add to canvas
Canvas.Childen.Add(button);
//set Control coordinates within the canvas
Canvas.SetLeft(button, MainWindow.xCoord);
Canvas.SetTop(button, MainWindow.yCoord);
}
You can get fancier for your needs, like if you want the center of the button to be at the Coordinates, or if you want to prevent the Button from being drawn outside the canvas (like if the user click the very bottom right corner). But this should be enough to get a minimum working example.

GMap.NET Windows Forms move the map with the mouse

How in GMapControl it is correct to handle pressing and moving Google maps using the mouse?
GMapControl gMap = new GMapControl();
gMap.MouseDown += GMap_MouseDown;
private void GMap_MouseDown(object sender, MouseEventArgs e)
{
gMap.MouseMove += GMap_MouseMove;
}
private void GMap_MouseMove(object sender, MouseEventArgs e)
{
base.OnMouseMove(e);
//gMap.Position = new PointLatLng(X, Y);
}
You don't need any code to move the map. The default is for the RIGHT mouse button to move the map, which I found rather awkward. To change to the LEFT mouse, use code like this in the Load() event of your Form:
gMap.DragButton = MouseButtons.Left;

MouseButtonEventArgs.GetPostion & MouseEventArgs.GetPostion

I am trying to do a drag and drop in DataGrid View.
I have my DataGrid is defined inside a user control and the user control is hosted inside a tabcontrol
Now i am handling the following events
PreviewMouseLeftButtonDown="OnPreviewMouseLeftButtonDown"
PreviewMouseMove="OnPreviewMouseMove"
the handlers are defined as follows;
private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Point mousePos = e.GetPosition(null);
Vector diff = startPoint - mousePos;
if (e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{
// .......doing drag/drop work here.......
}
}
private void OnPreviewMouseMove(object sender, MouseEventArgs e)
{
startPoint = e.MouseDevice.GetPosition(null);
}
where startPoint is the internal variable of type Point
However always the vector diff inside OnPreviewMouseLeftButtonDown function is always zero.
to my surprise the same logic works inside a triewview control but not inside a the datagrid?
any help would be much appreciated
You always get a MouseMove event immediately before the LeftButtonDown event, so startPoint will always be the same as mousePos with your current code.
Swapping your handlers should fix it (code in PreviewLeftButtonDown should be in PreviewMouseMove, and startPoint should be set in PreviewLeftButtonDown).

Manipulating SurfaceScrollViewer content

I'm diving into WPF here and I can't figure some things with multitouch.
I've got two questions about SurfaceScrollViewer.
Easier one first: I've got a large photo I'm displaying with SurfaceScrollViewer, so I can pan around, but I can't figure out how to get the content to start out centered in the screen. I can't find any native alignment properties in SScrollViewer. If I give the content margins, it crops it. Same if I do a RenderTransform. If I do a LayoutTransform, it doesn't seem to do change. Any ideas?
I also want to give this content Zoom functionality while inside SurfaceScrollViewer. Really I'm trying to zoom and pan with the elastic effects of SSV. Should I write the manipulations out by hand or can I patch the functions in SSV to be able to zoom? It seems like SSV absorbs 2nd touches into its panning function. I'd have to write a Manipulation handler to send multi touches to the content, right?
My code looks something like this right now:
<Grid x:Name="LayoutGrid" Width="1950" Height="1118" HorizontalAlignment="Center" >
<s:SurfaceScrollViewer x:Name="scrollViewer" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" >
<local:FloorView x:Name="floorViewer" Width="4209" Height="1442" >
<local:FloorView.LayoutTransform>
<TranslateTransform X="1000" />
</local:FloorView.LayoutTransform>
</local:FloorView>
</s:SurfaceScrollViewer>
</Grid>
Any help is much appreciated. Thanks!
figured out the first part:
scrollViewer.ScrollToHorizontalOffset(x);
scrollViewer.ScrollToVerticalOffset(y);
looks like i'll have to control manipulation events on the SSV to add zoom.
figured out the second part to zoom inside scrollviewer
handle touchdown events on the scrollviewer
send one touches to surfacescrollviewer and
send two touches to the content
enable manipulations on content
handle manipulations with the scrollviewer as the container
then use the delta manipulations to add a ScaleTransform to the content
don't forget to handle touchup events
private void floorViewer_TouchDown(object sender, TouchEventArgs e) //catch touch events on floorviewer
{
Touch1ID = e.TouchDevice.Id - 16777216; ;
if (Touch1ID == 0) //if one touch present, TouchDevice.Id is 2^24, two then 2^24+1 (this might just be my machine)
{
floorViewer.IsManipulationEnabled = false;
floorViewer.ReleaseTouchCapture(e.TouchDevice);
scrollViewer.CaptureTouch(e.TouchDevice);
}
else {
floorViewer.IsManipulationEnabled = true;
foreach(TouchDevice device in scrollViewer.TouchesOver){
scrollViewer.ReleaseTouchCapture(device);
floorViewer.CaptureTouch(device);
}
}
StartTimeout();
e.Handled = true;
}
void scrollViewer_TouchUp(object sender,TouchEventArgs e)
{
clearID();
e.Handled = true;
}
private void clearID()
{
Touch1ID = 0;
}
private void floorview_TouchUp(object sender, TouchEventArgs e)
{
clearID();
e.Handled = true;
}
//manipulators on floorviewer when it gets touches passed to it
private void scrollViewer_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
{
e.ManipulationContainer = scrollViewer;
e.Handled = true;
}
private void scrollViewer_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
double oldScale = flrScale;
flrScale *= e.DeltaManipulation.Scale.X;
if (flrScale < .95 | flrScale > 2) flrScale = oldScale;
floorViewer.RenderTransform = new ScaleTransform(flrScale, flrScale, e.ManipulationOrigin.X + flrInitX, e.ManipulationOrigin.Y + flrInitY);
e.Handled = true;
}
boom!

how to GetMousePosition anywhere on the screen, outside the bounds of window (or any Visual)

I'd like to track the position of the Mouse cursor, in screen coordinates, anywhere on the screen. So even if the mouse cursor moves outside the bounds of the window, is there a way to get the position of the mouse cursor?
What I'm doing is trying to get a popup to follow the mouse cursor, even if it moves off the main window.
Here is a code snippet of what I've tried (and hasn't worked):
private void OnLoaded(object sender, RoutedEventArgs e)
{
bool gotcapture = this.CaptureMouse();
Mouse.AddLostMouseCaptureHandler(this, this.OnMouseLostCapture);
}
Point mouse_position_relative = Mouse.GetPosition(this);
Point mouse_screen_position = popup.PointToScreen(mouse_position_relative);
private void OnMouseLostCapture(object sender, MouseEventArgs e)
{
bool gotcapture = this.CaptureMouse();
this.textblock.Text = "lost capture.";
}
What exactly was your problem?
Wait! There is a way to position a Popup relative to the screen. see PlacementMode.AbsolutePoint
This showed little happy face flying around:
private Popup _popup;
public Window1()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
_popup = new Popup
{
Child = new TextBlock {Text = "=))", Background = Brushes.White},
Placement = PlacementMode.AbsolutePoint,
StaysOpen = true,
IsOpen = true
};
MouseMove += MouseMoveMethod;
CaptureMouse();
}
private void MouseMoveMethod(object sender, MouseEventArgs e)
{
var relativePosition = e.GetPosition(this);
var point= PointToScreen(relativePosition);
_popup.HorizontalOffset = point.X;
_popup.VerticalOffset = point.Y;
}
Never mind, I realized there is no way to position a Popup relative to the screen, only relative to the Visual which contains it.
There are a number of ways to get the screen coordinates of the mouse position outside of a WPF Window. Unfortunately, you'll need to add references to use either of them, but it is possible. You can find examples of them both in #FredrikHedblad's answer to the How do I get the current mouse screen coordinates in WPF? question. Coincidentally, that question was answered a few days before you asked this question and gave up within 21 minutes of asking.

Resources