如何将 DotNetObjectReference 传递给 JS DOM 事件

xev*_*ryn 8 javascript c# blazor

我正在尝试在 Blazor 中使用 JS 拖放,一般情况下效果很好,但我想在活动期间设置自定义拖动图像ondragstart。一般来说,我的代码如下所示:

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

我遇到的问题是,我需要在设置拖动图像后调用 .Net 函数,但我找不到将所需的函数传递DotNetObjectReference到 JS 部分的方法。

简单地将新创建的 objectRef 传递到 JS 事件调用中会导致Unexpected end of input错误。

ondragstart="Element.dragStartHandler(event, '@(ImageSrcBase64)', @(DotNetObjectReference.Create(this)))"
Run Code Online (Sandbox Code Playgroud)

也使用 并JsonSerializer不能解决问题。它确实序列化了对象,并且 JS 能够反序列化它,但正如预期的那样,这些DotNet.invokeMethod()方法不存在。

ondragstart="Element.dragStartHandler(event, '@(ImageSrcBase64)', @(JsonSerializer.Serialize(DotNetObjectReference.Create(this))))"
Run Code Online (Sandbox Code Playgroud)

利用 Blazor 事件并在 .Net 中完全处理它并不能提供设置拖动图像的功能,因为传递的事件DragEventArgs不完全符合 JS 事件。

将事件参数传递IJSRuntime到 JS 函数中会导致错误,因为它与本机 JS 事件不同,因此至少setDragImage()缺少方法。

有什么办法可以让这个工作吗?我不想处理 JS-to-static-.Net 调用和 guid 或此类解决方法。


编辑
正如@MisterMagoo在现已删除的评论中提到的那样:这将是DotNetObjectReference在第一个周期中传递OnAfterRenderJS 部分以及静态 guid 并在需要时引用它的充分方法。

问题是,在我的例子中,列表很容易就会达到约 50-100 个条目长,而且我不知道这将如何影响内存的性能。所以在小情况下这会很好,但在我的情况下可能不会。


编辑
所以首先澄清我选择解决此问题的方式的原因:我确实知道我可以通过简单地创建跟随光标的图像来纯粹在 Blazor 中解决此问题。但是通过 JS,已经存在一种设置拖动图像的方法,该方法由浏览器本身在图像定位和移动方面进行处理。因此,我想采用性能最高效的路线,而不是充分利用 Blazor,因为我们的应用程序的性能窗口很窄。

use*_*663 0

这只是我在记事本中从内存中编写的错误伪代码,该代码确实指向循环,但它应该让您了解如何调用 javascript,然后将数据发送回 c#

在js文件中:

window.myBlazor = {
    doSomething: function(cSharpObjectReference, val1, val2) {
    // some js stuff happens
    cSharpObjectReference.Notify(someData);
}
Run Code Online (Sandbox Code Playgroud)

在.cs文件中:

public static class MyInterops
{
private static readonly string _BaseObjectContainer = "myBlazor";
        public static async Task DoSomethingCs(IJSRuntime jsRuntime, ObjectJavaScriptShouldUse cSharp, MyModel model)
        {
            await jsRuntime.InvokeVoidAsync($"{_BaseObjectContainer}.doSomething", DotNetObjectReference.Create(cSharp), model.Val1, model.Val2);
        }
}


public class ObjectJavaScriptShouldUse 
{
    private readonly IJSRuntime _jsRuntime;
    [JSInvokable]
    public async ValueTask Notify(MouseEvent eventArgs)
    {
       await MyInterops.DoSomethingCs(_jsRuntime, this, eventArgs); //i accidentally pointed these calls in recursion, but you get the idea
    }
}
Run Code Online (Sandbox Code Playgroud)