Saturday, 11 December 2021

How to pass DotNetObjectReference to JS DOM-event

I am trying to utilise JS drag & drop in Blazor, which works fine in general but I want to set a custom drag image during the ondragstart event. In general my code looks like this:

<div class="some-draggable-container"
     draggable="true"
     ondragstart="Element.dragStartHandler(event, '@(ImageSrcBase64)')" >
</div>
Element.dragStartHandler = function(event, imgSrcBase64) {
    var img = new Image();
    img.src = imgSrcBase64;
    event.dataTransfer.setDragImage(img, 0, 0);
}

The problem occurring to me is that I need to call a .Net function after setting the drag image and I cannot find a way to pass the needed DotNetObjectReference through to the JS part.

Simply passing the newly created objectRef into the JS event call leads to an Unexpected end of input error.

ondragstart="Element.dragStartHandler(event, '@(ImageSrcBase64)', @(DotNetObjectReference.Create(this)))"

Also using the JsonSerializer does not do the trick. It surely does serialise the object and JS is able to deserialise it, but as expected the DotNet.invokeMethod() methods are not present.

ondragstart="Element.dragStartHandler(event, '@(ImageSrcBase64)', @(JsonSerializer.Serialize(DotNetObjectReference.Create(this))))"

Utilising the Blazor event and handling it fully in .Net does not offer the ability to set the drag image because the passed DragEventArgs are not fully compliant to the JS one.

Passing the event args through IJSRuntime into a JS function leads to errors because it's just not the same thing as the native JS event, so at least the setDragImage() Method is missing.

Is there any way to make this work? I don't want to juggle around with JS-to-static-.Net calls and guids or that kind of workaround.


Edit
As @MisterMagoo mentioned in a now deleted comment: It would be a sufficient way to pass the DotNetObjectReference during the first cycle of OnAfterRender to the JS part as well as a static guid and reference it later if needed.

The problem with that is that in my case the list can easily be ~50-100 Entries long and I don't know how this would impact performance an memory. So in small cases this would be fine but in my case probably not.


Edit
So to clarify the reason of the way I choose to solve this problem in the first place: I do know that I could solve this problem purely in Blazor by simply creating an image that follows the cursor. But through JS there is an already existing way to set the drag image that is handled by the Browser itself in terms of image positioning and movement. So I wanted to go the most performance efficient route rather then fully utilising Blazor because we have a narrow performance window for our application.



from How to pass DotNetObjectReference to JS DOM-event

No comments:

Post a Comment