0

I'm writing a graphing program, and I want to be able to hover my mouse over a point on the graph to reveal details about the point. I'm aware of MouseHover(), but that only works when hovering over the form, not specific points on the form. I've written a function that works, but is incredibly resource intensive and not very reliable using MouseHover:
List<List<Point>> Points { get; set; } = new();

private async void GraphPanel_MouseHover(object sender, EventArgs e)
        {

            await Task.Run(() => {
                do
                {
                    foreach(var pointList in Points)
                    {
                        foreach (Point point in pointList)
                        {
                            if (Control.MousePosition == point)
                            {
                                throw new Exception();
                            }
                        }
                    }
                }
                while (true);
            });
        }

Is there a more practical way of doing this?

  • 4
    MouseMove gives you the position – pm100 Mar 13 '22 at 21:58
  • @pm100 e.Location in mousemove works the same as Control.MousePosition in this case, the issue comes when I iterate over a bunch of points to try to compare them to the current position in an endless loop – oglilprettythug Mar 13 '22 at 22:10
  • I have no idea what you code is trying to do so its impossible to give advice. YOu seem to be looping in the background over some points, but you dont show how those points get saved, not why you throw an exception when you find it. Reminder of how many points there are on the screen, if you want and exact match thats pretty precise – pm100 Mar 13 '22 at 22:14
  • I simply answered the question as asked. If you have a different question please update it – pm100 Mar 13 '22 at 22:15
  • You probably want to add some *tolerance* to those positions (your Points), otherwise it's quite difficult to hit a single Point with the mouse. You can exclude (with a `Where()` clause) all Points that have a X or Y position above or below the current `MousePosition` (translated to client coordinates) plus/minus the tolerance value. Transforming a Point in a Rectangle, in practice, so you have something like `Rectangle.Contains(Point)` -- Remove that `Task.Run()`, if needed, use a Timer instead. It can be activated/deactivatd using the Enter/Leave events. – Jimi Mar 13 '22 at 22:15
  • @pm100 the exception is so I know that I've successfully hit a point, the program stops. I don't think it's important to show how the points get saved, I've shown what the variable `Points` is as a list of a list of Points, that should be enough, and it's not part of the problem I'm having. – oglilprettythug Mar 13 '22 at 22:25
  • @Jimi I think tolerance is exactly what I need, I'll give this and the other suggestions you made a try, thanks! – oglilprettythug Mar 13 '22 at 22:30
  • Probably will be helpful https://stackoverflow.com/questions/1316681/getting-mouse-position-in-c-sharp – Eugene Mar 14 '22 at 00:01

1 Answers1

0

MouseHover is called a lot of times. You can:

  • Save mouse position into a variable in MouseHover. Save the currentTime (DateTime.UtcNow) in other variable.
  • Use Task.Delay to wait, for example, 100 ms. In the code executed after this delay, check if current mouse position is the same (o closest if you want work with some tolerance). Then, the mouse was 100 ms in the same position: do your work. If not, do nothing.
  • Avoid create a new Task if (DateTime.UtcNow-YourPreviouslySavedDate).TotalMilliSeconds is less than 100 ms

Another option is using Timer component. Set the interval and attach a method for the event (double click in the component). On the event, check mouse position and do your work.

Victor
  • 2,313
  • 2
  • 5
  • 13