In my very simple WPF app, I have a canvas with a bitmap image that I'm wanting to allow the user to "capture" a section of. In order to select this section, the user should click the left mouse button down (which selects the "top left") and then, keeping the button down, move to the "bottom right" and release the left button - this completes the selected area . In order to highlight what has been selected, I'm drawing a red rectangle - which moves as the mouse moves.
My initial idea was that once the button was clicked down, I could detect that by the OnMouseLeft down event. And I would detect the release by the the OnMouseLeftUp event. The first part seems to be working fine but the OnMouseLeftUp doesn't seem to be fired, at least not if a I "drag" the mouse while the left button is down, and then release it. (It does seem to fire if I click the left button quickly.)
I've got around this problem by checking in the OnMouseMove event whether the mouse left is still down. This works, so my code is achieving what I want it to do. However, I'm still curious as to why does the OnMouseLeftUp event not seem to fire? I still not sure what was wrong with my original approach. I've done some searching and have come across suggestions that maybe another event (perhaps the OnMouseMove?) is pre-empting that OnMouseLeftUp event and that I need to subscribe to the PreviewMouseLeftButtonUp event. I tried that without success either - but I definitely wasn't sure what i was doing wrong!
<Window x:Class = "WpfApp_Mouse_Test.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local = "clr-namespace:WpfApp_Mouse_Test"
mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "604">
<StackPanel>
<Canvas x:Name = "canvas" Background = "LightBlue"
MouseMove = "OnMouseMove"
MouseLeftButtonDown="OnMouseLeftDown"
MouseLeftButtonUp = "OnMouseLeftUp"
Height = "150" Margin = "20">
</Canvas>
<TextBlock x:Name = "txt1" Height = "31" HorizontalAlignment = "Right"
Width = "250" Margin = "0,0,294,0" />
</StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WpfApp_Mouse_Test
{
public partial class MainWindow : Window
{
bool mouseLeftStillDown = false;
Point startPos = new Point();
Rectangle markerRect;
public MainWindow()
{
InitializeComponent();
//canvas.AddHandler(MouseLeftButtonUpEvent, new RoutedEventHandler(canvas_MouseUp), true);
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
if(e.LeftButton == MouseButtonState.Released)
{
mouseLeftStillDown = false; //I need this because the MouseLeftUp event doesn't seem to fire
}
//Draw Rectangle
if (mouseLeftStillDown)
{
canvas.Children.Remove(markerRect); //Remove old rectangle
markerRect = new Rectangle()
{
Width = Math.Abs(e.GetPosition(canvas).X - startPos.X),
Height = Math.Abs( e.GetPosition(canvas).Y - startPos.Y),
Fill = Brushes.Transparent, Stroke = Brushes.Red, StrokeThickness = 1
};
canvas.Children.Add(markerRect);
Canvas.SetLeft(markerRect, Math.Min(startPos.X,e.GetPosition(canvas).X));
Canvas.SetTop(markerRect, Math.Min(startPos.Y, e.GetPosition(canvas).Y));
}
txt1.Text = $"Mouse left button down: {mouseLeftStillDown.ToString()} ";
}
private void OnMouseLeftDown(object sender, MouseButtonEventArgs e)
{
mouseLeftStillDown = true;
canvas.Children.Remove(markerRect); //Remove old rectangle
startPos = e.GetPosition(canvas);
txt1.Text = "(OnMouseLeftDown) left button down : " + mouseLeftStillDown.ToString();
}
//This doesn't seem to fire on release of the left mouse button - at least not regularly!
private void OnMouseLeftUp(object sender, MouseButtonEventArgs e)
{
mouseLeftStillDown = false;
txt1.Text = "(OnMouseLeftUp) left button down : " + mouseLeftStillDown.ToString();
}
}
}