C# 如何处理GetDataPresent以使其接受所有派生类型

C# 如何处理GetDataPresent以使其接受所有派生类型,c#,winforms,drag-and-drop,C#,Winforms,Drag And Drop,我使用来确定拖动的组件是否可接受 我有一个问题,那就是我想要接受一个特定的类型,比如SomeType,以及从它派生的所有类型。似乎GetDataPresent不支持此类要求 有什么想法吗?我以前也回答过类似的问题: 您可以做的是创建一个容器类,它保存您正在拖动的数据。然后在GetDataPresent中检查容器类类型,如果它存在,则可以读取包含数据实际实例的内容成员 下面是一个快速示例,如果您的基类型是DragDropBaseData,则可以创建以下DragDropInfo类 public cl

我使用来确定拖动的组件是否可接受

我有一个问题,那就是我想要接受一个特定的类型,比如SomeType,以及从它派生的所有类型。似乎
GetDataPresent
不支持此类要求


有什么想法吗?

我以前也回答过类似的问题:

您可以做的是创建一个容器类,它保存您正在拖动的数据。然后在GetDataPresent中检查容器类类型,如果它存在,则可以读取包含数据实际实例的内容成员

下面是一个快速示例,如果您的基类型是DragDropBaseData,则可以创建以下DragDropInfo类

public class DragDropInfo 
{ 
  public DragDropBaseData Value { get; private set; } 

  public DragDropInfo(DragDropBaseData value) 
  { 
    this.Value= value; 
  } 
}
然后可以使用以下命令启动拖放,其中DrafDropDerivedData是从DragDropBaseData派生的类

DoDragDrop(new DragDropInfo(new DragDropDerivedData() ), DragDropEffects.All); 
您可以使用以下命令访问拖动事件中的数据

e.Data.GetData(typeof(DragDropInfo)); 

只是不要使用GetDataPresent(),它是样板文件,但您可以按照自己的方式进行操作。实际检索对象并检查您是否满意其类型:

    protected override void OnDragEnter(DragEventArgs drgevent) {
        var obj = drgevent.Data.GetData(drgevent.Data.GetFormats()[0]);
        if (typeof(Base).IsAssignableFrom(obj.GetType())) {
            drgevent.Effect = DragDropEffects.Copy;
        }
    }

其中Base是基类的名称。虽然GetFormats()的使用看起来很奇怪,但这种方法肯定会起作用,因为拖动.NET对象只会生成一种格式,即对象类型的显示名称。这也是GetDataPresent无法用于派生对象的原因。

我也遇到了类似的问题。我希望它只在接口上使用DragDrop,这不起作用。 因此,我将数据放入一个对象数组中

DoDragDrop(_dragDropSource, new[] { _dragDropSource.DataContext }, DragDropEffects.Move);

if (((object[]) e.Data.GetData(typeof(object[])))?[0] is ICatTreeViewGroup group) {
  // do something with a group
}

谢谢克里斯,回答得很好,但请看汉斯的回答。@法国男孩,汉斯给了一个很好的回答。它需要更多的反射基础设施,而不仅仅是像我的例子中那样知道所有派生类型都封装在一个名为DragDropInfo的已知类型中,但我严重怀疑反射会是一个问题,所以这是一个简洁的答案。谢谢!这个问题涵盖了我的确切问题,答案是完美的解决方案!:)