I tried a few ways today (about one month ago, but I wrote the beginning of this post, except for this part, a month ago) to implement a drag and drop feature in my Blazor app, for now I got the essential functionality of what I wanted in a way I didn’t see in these blog posts that I had a look at:
- Drag-N-Drop File Upload In Blazor Using JS Interop And Minimal API (Part 1)
- A Simple To-Do App Using JS Interop with HTML5 Drag and Drop in Blazor WebAssembly
- Investigating Drag and Drop with Blazor
Also see Microsoft Won’t Do Drag-and-Drop for Blazor.
The examples linked to above did not seem to quite fit my use case where all of the dragging and dropping logic isn’t limited to a single component. I thought the HTML drag and drop API could be used pretty directly to do what I needed to do, but when I tried that I ran into some issues with not seeing how to use the DataTranfer type. It seems like these .NET types for the drag and drop JS event object may be incompletely implemented and I also never found an example showing a correct way of passing the DragEventArgs
argument to the .NET event handler callback being passed into the JavaScript method called via the JSRuntime service, which I was doing but then the JS object didn’t have the expected members which may have been due to it being different or I was doing it wrong.
I ended up doing something pretty to solve my problem. I have a class to hold an object representing what is being dragged:
The class uses a generic type T
currently. It needs to be registered as a service so it can be injected into the Razor components where it is needed. My app is a Blazor Web App that uses prerendering (that happens on the server, with the main rendering being Blazor client-side rendering). This means that the services that are injected into Razor components need to be registered on both the server and client project, which I accomplish with this class:
So in the client project Program.cs
:
And some example code of one of the Razor components that uses this:
The drop
event always fires before the dragend
event. There are some other things here worth commenting on but to be honest the beginning of this blog post was written about a month ago and I’m just finishing it now. I found that the syntax for attaching the Razor event handlers was tricky to make it work correct just from reading the docs and I had to experiment a bit to get the above syntax which worked. Due to the way event firing is in JavaScript (bubbling and capture and all that) it was necessary to keep track of how many nested levels of dragenter there are to highlight the dropzone correctly by adding a CSS class (dragover-highlight
) to it.