Image cannot be moved by left mouse drag.

ichiro kanazawa 80 Reputation points
2023-07-13T06:08:31.7633333+00:00

Thank you for reading my message.

I have a question about the .net maui blazor program.
I am creating an application that places an image on the screen and moves it by mouse dragging. Right-click and middle-click work as expected, but left-click only moves slightly and does not work as expected. A sample program is shown below.

@page "/"
@using Microsoft.AspNetCore.Components.Web

<img src="/b.png" style="position:absolute; left:200px; top:500px; width: 2200px; height: 800px;
      @onmouseup="StopDraggingImage" @onmousemove="HandleMouseMove"
  />
  @foreach (var (image, index) in images.Select((v, i) => (v, i)))
{
     <img src="@image.Path" style=@image.Style @onmousedown="(args) => StartDraggingImage(index, args)" @onmouseup="StopDraggingImage" @onmousemove="HandleMouseMove" />
}

@using System;
@using System.Drawing;
@using System.Drawing.Imaging;

@code {
     public class ImageInfo
     {
         public string Data { get;
         public string Path { get;
         public int Top { get;
         public int Left { get;
         public string Style { get;
         public bool isDragging { get;
     }
     private List<ImageInfo> images = new List<ImageInfo>(){};
     private double startX = 0;
     private double startY = 0;

     protected override void OnInitialized()
     {
         base.OnInitialized();

         for (var i = 0; i < 2; i++)
         {
             ImageInfo image = new ImageInfo();
             image.Path = "/c" + (i + 1).ToString() + ".png";
             image.Top = 500;
             image. Left = 250 + i * 650;
             image.Style = string.Format("position:absolute; left:{0}px; top:{1}px;", image.Left, image.Top);
             image.isDragging = false;
             images.Add(image);
         }

         OnAfterRenderAsync();
     }

     void OnAfterRenderAsync()
     {
         foreach (var image in images)
         {
             image.Style = $"position:absolute; left:{image.Left}px; top:{image.Top}px;";
         }
     }


     protected void StartDraggingImage(int imageNumber, MouseEventArgs e)
     {

         images[imageNumber].isDragging = true;

         startX = e.ClientX - images[imageNumber].Left;
         startY = e.ClientY - images[imageNumber].Top;

         OnAfterRenderAsync();
     }

     protected void HandleMouseMove(MouseEventArgs e)
     {
         foreach (var image in images)
         {
             if (image.isDragging)
             {
                 image.Left = (int)(e.ClientX - startX);
                 image.Top = (int)(e.ClientY - startY);
             }
         }
         OnAfterRenderAsync();
     }

     protected void StopDraggingImage(MouseEventArgs e)
     {
         foreach (var image in images)
         {
             image.isDragging = false;
         }
     }

}
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,663 questions
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,904 questions
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 71,101 Reputation points
    2023-07-13T16:15:21.3866667+00:00

    you are capturing mouse events based on an element. as soon as the mouse moves off the element, you stop receiving these events. this is fine for down click, but for the move you want the window or bounding element. for up you need to use the window to always capture.

    you will need to define blazor callbacks for the mouse events:

    https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-dotnet-from-javascript?view=aspnetcore-7.0

    just add the javascript:

    window.addEventListener("mouseup", (e) => DotNet.invokeMethodAsync(assName,"MouseUp",e.x,e.y);
    window.addEventListener("mousemove", (e) => DotNet.invokeMethodAsync(assName,"MouseMove",e.x,e.y);
    

    I also question updating the style in the after render. this just sets the values used in the next render operation. you were forced to call it during render. just rename the method as it is not an after render operation. after render is used to access the true dom after the component render typically via js interop.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.