Left button pressed in mouse move in wpf - wpf

On mouse move of a grid, left button pressed is not caught, but right button pressed is caught. Any one know the reason?
private void grid1_MouseMove(object sender, MouseEventArgs e)
{
if (e.RightButton == MouseButtonState.Pressed)
{
//Entered to the loop
}
}
private void grid1_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
//Not enter to the loop
}
}

There could be any number of reasons, but as you didn't provide a Minimal, Complete, and Verifiable example, we can't really tell you for sure. There is certainly nothing wrong with the following code, that works as expected in a new project:
private void grid1_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
//Entered the loop
}
if (e.RightButton == MouseButtonState.Pressed)
{
//Entered the loop
}
}
The most likely reasons why your code never entered your if statement are as follows:
You weren't moving the mouse when clicking the left mouse button.
You weren't over the Grid, when you clicked the left mouse button.
You are handling the left click in a tunnelling event (Preview... event) and setting e.Handled to true.
If these suggestions do not help, then please follow the advice in the linked help page and provide a Minimal, Complete, and Verifiable example that we can use to further help.

Related

if Right button pressed on console

Good morning,
I would like to know if my right mouse button is held down.
For this I thought of System.Windows.Input.Mouse but I get this error if I execute the following code:
while (true)
{
if (Mouse.RightButton == MouseButtonState.Pressed)
{
}
}
Error : Unmanaged exception: System.InvalidOperationException: The calling thread must be in STA mode, as required by the name
Is there an alternative or something that would work as a console?
Thanks
Try using it inside a function like this :
private void PressLeftButton(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
MessageBox.Show("The Left Mouse Button is pressed");
}
}

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).

How do I go about implementing drag delta on shapes

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.

Releasing mouse capture and letting mouse click pass through

I have a control that is similar to a Popup or Menu. I want to display it and when the user clicks outside the bounds of the box, have it hide itself. I've used Mouse.Capture(this, CaptureMode.SubTree) as well as re-acquired the capture the same way Menu/Popup do in OnLostMouseCapture.
When the user clicks outside the bounds of the control, I release the mouse capture in OnPreviewMouseDown. I don't set e.Handled to true. The mouse click will make it to other controls on the main UI, but not to the close button (Red X) for the window. It requires 2 clicks to close the app.
Is there a way to tell WPF to restart the mouse click, or to send a repeated mouse click event?
Here's my code. Note I renamed it to MainMenuControl - I'm not building a Menu, so Menu/MenuItem and Popup aren't options.
public class MainMenuControl : Control
{
static MainMenuControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MainMenuControl), new FrameworkPropertyMetadata(typeof(MainMenuControl)));
}
public MainMenuControl()
{
this.Loaded += new RoutedEventHandler(MainMenuControl_Loaded);
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnPreviewMouseDownOutsideCapturedElementHandler);
}
void MainMenuControl_Loaded(object sender, RoutedEventArgs e)
{
this.IsVisibleChanged += new DependencyPropertyChangedEventHandler(MainMenuControl_IsVisibleChanged);
}
void MainMenuControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (this.IsVisible)
{
Mouse.Capture(this, CaptureMode.SubTree);
Debug.WriteLine("Mouse.Capture");
}
}
// I was doing this in OnPreviewMouseDown, but changing to this didn't have any effect
private void OnPreviewMouseDownOutsideCapturedElementHandler(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("OnPreviewMouseDownOutsideCapturedElementHandler");
if (!this.IsMouseInBounds())
{
if (Mouse.Captured == this)
{
Mouse.Capture(this, CaptureMode.None);
Debug.WriteLine("Mouse.Capture released");
}
Debug.WriteLine("Close Menu");
}
}
protected override void OnLostMouseCapture(MouseEventArgs e)
{
base.OnLostMouseCapture(e);
Debug.WriteLine("OnLostMouseCapture");
MainMenuControl reference = e.Source as MainMenuControl;
if (Mouse.Captured != reference)
{
if (e.OriginalSource == reference)
{
if ((Mouse.Captured == null) || (!reference.IsAncestorOf(Mouse.Captured as DependencyObject)))
{
//TODO: Close
Debug.WriteLine("Close Menu");
}
}
// if a child caused use to lose the capture, then recapture.
else if (reference.IsAncestorOf(e.OriginalSource as DependencyObject))
{
if (Mouse.Captured == null)
{
Mouse.Capture(reference, CaptureMode.SubTree);
Debug.WriteLine("Mouse.Capture");
e.Handled = true;
}
}
else
{
//TODO: Close
Debug.WriteLine("Close Menu");
}
}
}
private bool IsMouseInBounds()
{
Point point = Mouse.GetPosition(this);
Rect bounds = new Rect(0, 0, this.Width, this.Height);
return bounds.Contains(point);
}
}
The problem is that the mouse handling you are talking about is outside the WPF eventing system and part of the operating system so we're really talking about two fairly different mouse message queues that interact well enough most of the time but in these edge case we see that the interoperability is not perfect.
You could try to generate Win32 mouse messages or send your own window a close message but all those approaches are hacks. Since popups and menus exhibit exactly the same symptoms you describe, it doesn't seem like there is going to be an easy to way to accomplish what you want as you've described it.
Instead, I suggest that you consider giving up the mouse capture when the mouse leaves the north client area of the window or some other heuristic such as a specified distance from the control. I know this is probably not ideal but it might be a satisfactory compromise if you want the close button to work badly enough.

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