You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor拖拽功能:如何获取目标对象?

Blazor拖拽功能中获取目标对象的解决方案

问题分析

你当前的代码其实已经通过@ondrop="@((e) => ondropOver(b, blocks.ToList()))"将目标块b传递到了ondropOver方法中,但可能因为以下原因导致无法正确获取或处理目标块:

  • 传递blocks.ToList()创建了列表副本,修改副本不会同步到原数据集合
  • 未及时调用StateHasChanged()触发组件渲染,导致状态更新不生效
  • 排序逻辑仅直接赋值Order,未处理其他块的顺序冲突

修正后的前端代码

<div class="pos-top">
    <div id="imgGrid" class="grid bg-white" style="grid-template-columns:repeat(@columnCount, @(unitWidth)); grid-auto-flow:dense;">
        @foreach (var b in blocks)
        {
            @if ((b.Placement[_pageType].Visible == true || showHiddenBlocks == true) && b.Zones != null && b.Zones.Contains(zone))
            {
                var id = b.Id;
                <div class="col-span-@b.ColSpan row-span-@b.RowSpan relative border border-black box-border @(b.isDragOver?"dropped":"")" 
                     style=" order:@b.Placement[_pageType].Order;" 
                     @ondblclick="(() => ChangeBlockProperties(b))"
                     draggable="true"
                     data-block-id="@b.Id"
                     id="@id" 
                     @ondrop="(() => ondropOver(b))"
                     @ondragover="OnDragOver"
                     @ondragstart="@((e) => ondragstart(e, b))"
                     @ondragenter="@(() => ondragenter(b))"
                     @ondragleave="@(() => ondragleave(b))"
                     @ondragend="@(() => ondragend(b))">
                    <div class="blockNumberInfo absolute rounded-full bg-red-700 flex justify-center items-center border-2 border-black"
                         style="width:40px;height:20px">
                        @b.LocalIndex / @b.Placement[_pageType].Order
                    </div>
                </div>
            }
        }
    </div>
</div>

修正后的后端处理代码

// 处理dragover,必须调用PreventDefault才能触发drop事件
public void OnDragOver(DragEventArgs e)
{
    e.PreventDefault();
    e.DataTransfer.DropEffect = "move";
}

public void ondragstart(DragEventArgs e, FlyerBlock item)
{
    e.DataTransfer.EffectAllowed = "move";
    DraggedItem = item;
    DraggedItemPosition = item.Placement[_pageType].Order;
}

public void ondragenter(FlyerBlock item)
{
    if (DraggedItem?.Id == item.Id) return;
    item.isDragOver = true;
    DragEnter = item;
    StateHasChanged(); // 触发渲染更新拖拽状态
}

public void ondragleave(FlyerBlock item)
{
    item.isDragOver = false;
    StateHasChanged();
}

public async Task ondropOver(FlyerBlock targetItem)
{
    DragEnter = null;
    if (DraggedItem == null || DraggedItem.Id == targetItem.Id) return;

    var draggedOrder = DraggedItem.Placement[_pageType].Order;
    var targetOrder = targetItem.Placement[_pageType].Order;

    // 调整其他块的顺序,避免Order值重复
    if (draggedOrder < targetOrder)
    {
        // 拖拽项向后移动,目标及后续块的Order减1
        foreach (var block in blocks.Where(b => b.Placement[_pageType].Order > draggedOrder && b.Placement[_pageType].Order <= targetOrder))
        {
            block.Placement[_pageType].Order--;
        }
    }
    else
    {
        // 拖拽项向前移动,目标及前面块的Order加1
        foreach (var block in blocks.Where(b => b.Placement[_pageType].Order >= targetOrder && b.Placement[_pageType].Order < draggedOrder))
        {
            block.Placement[_pageType].Order++;
        }
    }

    // 设置拖拽项的新顺序
    DraggedItem.Placement[_pageType].Order = targetOrder;
    
    // 保存更改,直接使用组件的原blocks集合
    await BlockplacementEditService.SaveBlockChangesAsync(blocks, DraggedItem, targetOrder, _pageType, zone);
    
    DraggedItem = null;
    targetItem.isDragOver = false;
    StateHasChanged(); // 更新UI状态
}

public void ondragend(FlyerBlock item)
{
    item.isDragOver = false;
    DraggedItem = null;
    DragEnter = null;
    StateHasChanged();
}

关键修改点

  1. 移除列表副本传递:直接使用组件的blocks集合,避免修改副本导致数据不同步
  2. 强制触发状态更新:在修改isDragOver和Order值后调用StateHasChanged(),确保UI实时更新
  3. 完善排序逻辑:处理其他块的Order值,避免出现重复排序号
  4. 规范dragover事件:单独提取方法并调用PreventDefault(),确保drop事件能正常触发

内容的提问来源于stack exchange,提问作者Adil15

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:24:20