我正在尝试使用JS拖动&Blazor中的drop,它通常工作得很好,但我想在ondragstart
事件期间设置一个自定义拖动图像。一般来说,我的代码如下:
<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);
}
我遇到的问题是,在设置拖动图像后,我需要调用.Net函数,并且我找不到将所需的DotNetObjectReference
传递到JS部分的方法。
简单地将新创建的objectRef传递到JS事件调用中会导致Unexpected end of input
错误。
ondragstart="Element.dragStartHandler(event, '@(ImageSrcBase64)', @(DotNetObjectReference.Create(this)))"
同样,使用JsonSerializer
也不起作用。它确实串行化了对象,JS能够取消对它的串行化,但正如预期的那样,DotNet.invokeMethod()
方法并不存在。
ondragstart="Element.dragStartHandler(event, '@(ImageSrcBase64)', @(JsonSerializer.Serialize(DotNetObjectReference.Create(this))))"
利用Blazor事件并在.Net中完全处理它并不能提供设置拖动图像的能力,因为传递的DragEventArgs
不完全符合JS事件。
将事件args通过IJSRuntime
传递到JS函数会导致错误,因为它与本地JS事件不同,所以至少缺少setDragImage()
方法。
有什么办法让它发挥作用吗?我不想在JS到静态.Net调用和guid或诸如此类的变通方法之间周旋。
编辑
正如@MisterMagoo在一条现已删除的评论中提到的那样:在OnAfterRender
的第一个周期中将DotNetObjectReference
传递给JS部分以及一个静态guid,并在需要时稍后引用它,这将是一种足够的方式。
问题是,在我的情况下,列表的长度很容易达到50-100个条目,我不知道这会对内存的性能产生什么影响。所以在小的情况下,这是可以的,但在我的情况下可能不是。
编辑
因此,首先要澄清我选择解决此问题的方式的原因:我知道,我只需创建一个跟随光标的图像,就可以完全在Blazor中解决此问题。但通过JS,已经存在一种设置拖动图像的方法,该方法由浏览器本身在图像定位和移动方面进行处理。因此,我想走性能效率最高的路线,而不是充分利用Blazor,因为我们的应用程序的性能窗口很窄。
这只是我在记事本中用内存编写的糟糕的psuedo代码,代码确实指向了一个循环,但它应该让你知道如何调用javascript,然后将数据发送回c#
在js文件中:
window.myBlazor = {
doSomething: function(cSharpObjectReference, val1, val2) {
// some js stuff happens
cSharpObjectReference.Notify(someData);
}
在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
}
}