C# Winforms通过互操作控制拖放注册

C# Winforms通过互操作控制拖放注册,c#,winforms,vsto,C#,Winforms,Vsto,恐怕是很长的一段,但请耐心听我说 我有一个VSTO项目,它允许将Outlook项目、邮件、附件等拖放到winforms控件上,特别是一个托管在Outlook内部CustomTaskPane中的TreeView,它通过突出显示正在拖动的文件夹来提供通常的UI反馈。 我已经将TreeView的AllowDrop属性设置为true,我想要的所有事件都已启动,一切都很正常 但是,在Outlook 2010之前的旧版本中,我有一种情况,即VSTO公开的对象模型较旧,并且我无法访问属性,这些属性允许我捕获通

恐怕是很长的一段,但请耐心听我说

我有一个VSTO项目,它允许将Outlook项目、邮件、附件等拖放到winforms控件上,特别是一个托管在Outlook内部CustomTaskPane中的TreeView,它通过突出显示正在拖动的文件夹来提供通常的UI反馈。 我已经将TreeView的AllowDrop属性设置为true,我想要的所有事件都已启动,一切都很正常

但是,在Outlook 2010之前的旧版本中,我有一种情况,即VSTO公开的对象模型较旧,并且我无法访问属性,这些属性允许我捕获通过Outlook iself通过托管代码拖动的内容

我已经通过直接挂接到本机Windows拖放解决了这个问题。允许此操作的代码非常广泛,涉及大量互操作工作,但关键是我必须通过以下方式注册控件-

[DllImport("OLE32.DLL", ExactSpelling = true, CharSet = CharSet.Auto, PreserveSig = false)]
    public static extern void RegisterDragDrop(HandleRef hwnd, IOleDropTarget target);
我扩展了TreeView类并实现了IOleDropTarget,以允许通过此方法注册我的新控件类。同样,这非常有效,经过一点c魔法后,在treview中任何地方丢弃的任何东西都会将丢弃的对象作为字节数组提供给我,我可以使用它

问题出在这里 通过interop注册TreeView意味着我不能使用它的AllowDrop属性注册它。尝试同时执行这两个操作会抛出一个错误,告诉我只能为拖放注册一个控件一次。仅通过互操作注册它会完全绕过“托管”注册,就TreeView而言,它没有注册,这意味着我没有收到任何拖放事件,也无法处理对用户的任何反馈

是否有任何方法可以使用互操作注册方法,同时告诉同一个控件它是通过常用的winforms方法注册的拖放? 或者,任何人都可以想出任何聪明的方法来覆盖控件,以便我从TreeView获得反馈,并从interop registerd控件获得丢弃的事件吗

希望这一切都有意义


非常感谢您的回答。

Ugh。你所做的一切解决了你的问题,这毫无意义。AllowDrop=true已调用RegisterDragDrop。如果旧版本的Outlook出现问题,则问题应该出现在DragEnter事件处理程序中,该处理程序识别被拖动的对象。查看在该事件中调用e.Data.GetFormats得到的结果。最坏的情况是-您可能需要有两个单独的构建配置…只需使用构建时间常量来触发使用哪个TreeView。Outlook 2010之前的用户需要使用非托管注册的安装程序,而Outlook 2010+可以使用托管注册。