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

Winforms C# .NET Framework 同Grid拖拽文件重复问题如何解决

网格控件拖拽重复复制问题修复方案

问题根因

  • 现有逻辑未区分拖拽数据来源,只要识别到文件拖放格式就会执行添加逻辑,从自身控件发起的拖拽再放回时也会触发新增
  • File.Exists(file)校验逻辑完全无效:你要规避的是网格内附件条目的重复,而非磁盘文件重复,拖入的文件本身在磁盘上就是存在的,所以这个判断不会起到拦截作用

修复步骤

1. 拖拽发起时增加自定义来源标记

在MouseDown事件中给拖拽数据对象添加自定义格式标记,标识本次拖拽来自当前网格控件

2. 拖入校验时拦截自身来源的拖拽

在DragEnter事件中识别到自身发起的拖拽时,直接禁用拖放效果,不会触发后续Drop逻辑

3. Drop逻辑增加条目重复校验(双重保险)

即使前面的校验漏过,Drop时先校验当前网格已有的附件列表中是否存在对应文件,不存在才执行添加操作

完整修改后代码

_attachmentGrid.DragEnter += (s, e) =>
{
    // 优先判断是否是自身发起的拖拽,直接拦截
    if (e.Data.GetDataPresent("Custom_AttachmentGrid_SelfSource"))
    {
        e.Effect = DragDropEffects.None;
        return;
    }
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        e.Effect = DragDropEffects.Copy;
    }
    else
    {
        e.Effect = DragDropEffects.None;
    }
};

_attachmentGrid.DragDrop += (s, e) =>
{
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
    if (files == null || files.Length == 0) return;
    
    // 取当前网格已绑定的附件列表,这里替换成你实际的数据源获取逻辑
    var existAttachments = _attachmentGrid.DataSource as List<你的附件实体类型>;
    
    foreach (string file in files)
    {
        string fileName = Path.GetFileName(file);
        // 校验当前列表中是否已存在同路径/同名的附件,不存在才添加
        if (!existAttachments.Any(x => x.FileAttachment.AttachmentName == fileName))
        {
            AttachFile(file);
        }
    }
};

_attachmentGrid.MouseDown += (s, e) =>
{                           
    byte[] data = GetData(_selection.SingleSelection);
    string fileName = _selection.SingleSelection.Entity.FileAttachment.AttachmentName;
    var list = new StringCollection();
    list = _manager.DragAttachment(data, fileName);
    
    DataObject dataObject = new DataObject();
    dataObject.SetFileDropList(list);
    // 新增自定义来源标记
    dataObject.SetData("Custom_AttachmentGrid_SelfSource", true);
    _attachmentGrid.DoDragDrop(dataObject, DragDropEffects.Move | DragDropEffects.Copy);                  
};

补充说明

如果后续需要支持控件内部拖拽排序,只需要修改DragEnter的判断逻辑,自身来源时把Effect改成DragDropEffects.Move,然后在DragDrop中单独处理内部排序逻辑,不要调用AttachFile新增条目即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:54:04