我想从Silverlight UI元素中拖动一张图片并将其放置在用户的桌面或Windows资源管理器中。

7
我有一个包含图片的Silverlight控件。我希望用户能够将图像从Silverlight应用程序中拖出并放置在任何可以放置图像的位置。例如,放置到桌面、PowerPoint幻灯片或Word文档中。迄今为止,我所读的所有内容都说这是不可能的,但我很难相信。我对Silverlight和RIA开发非常陌生,因此非常感谢任何帮助。
下面是我的WinForm表单中的代码示例,但拖动从未开始。
string[] aString = { imagePath };
DataObject data = new DataObject(DataFormats.FileDrop, aString);
data.SetData(DataFormats.StringFormat, imagePath);
DoDragDrop(data, DragDropEffects.Copy);

你如何在WinForms中托管Silverlight? - Gabe
我们在表单中加载HTML和Silverlight内容。 - wheels53
那么你是在使用 WebBrowser 控件吗? - Gabe
是的。我们在WebBrowser控件中加载HTML和Silverlight插件。 - wheels53
3个回答

4
问题在于,Silverlight中的拖放操作无法简单地访问浏览器外部的任何内容(这是设计上的问题)。根据用户的设置,您甚至需要获取剪贴板操作和沙盒临时文件存储的明确许可。这听起来更适合WPF应用程序(也许使用Web部署?)或其他桌面应用程序技术。
然而,话虽如此,以下是一些您可以尝试/考虑的事情:
1. 在Internet Explorer中托管的Silverlight/Javascript/ActiveX组合 2. Silverlight 5“离线”和P/Invoke(我听说当Silverlight 5发布时将支持P/Invoke) 3. Silverlight连接到在同一台计算机上运行的Web服务(有点疯狂,但您没有要求“不疯狂”,您要求的是可能性)
我对Win32 API中的拖放操作不太熟悉,所以在确认这一点是否可能之前,需要进行大量的研究和实验(我已经可以告诉您,这并不实用)。 编辑:根据您提供的额外信息,我怀疑您正在尝试的事情是可能可以实现的。首先,您是使用WPF还是WinForms?我假设是WPF,但您的一个评论说是WinForms。我对WPF拖放操作不是很熟悉,但经过了解,我认为您的代码走在了正确的道路上。我创建了一个WPF应用程序,并在KeyDown事件期间启动了拖动操作。这意味着鼠标按钮不一定被按下。如果我在按钮被按下时启动了DragDrop,它就能工作。如果我在鼠标按钮没有被按下时启动了操作,我必须按下鼠标按钮,然后拖动操作才会开始(这是意外的,因为我以为鼠标必须已经被按下)。如果我在应用程序外按下鼠标,然后将WPF应用程序聚焦(ALT+Tab),然后在鼠标按钮仍然被按下时启动DragDrop,它就不会工作。我获取了MouseDevice的引用并检查了LeftButton属性,状态显示为“Released”,即使按钮仍然被按下。似乎关键在于拖放操作与内部鼠标状态的交互方式。您可能需要找到一种设置鼠标状态的方法(也许是使用UI自动化API?)。此时,这整个过程显然是一个hack(尽管可能有办法使其工作)。

1
澄清。我们使用WinForms在Windows上托管我们的Silverlight插件。当RIA中发生左键按下事件时,会向主Windows表单发送一条消息,其中包含要拖动的图像的绝对文件路径。在主窗体中,我使用原始帖子中指示的代码初始化拖动。我没有收到任何错误,但是拖动不起作用。 - wheels53
谢谢Adam。你能提供一些模拟MouseDown/MouseCapture的示例代码吗? - wheels53
对于任何困惑感到抱歉。是WinForms,而不是WPF。测试结果很有趣。我将尝试自动化在表单上按下鼠标,并查看是否开始拖动。 - wheels53
我正在考虑的下一种方法涉及启动拖放操作,将图像复制到系统剪贴板,然后在鼠标光标移动时处理标签图像的绘制。然后,在释放左键时从剪贴板执行系统粘贴。我对此的担忧是使用剪贴板可能会产生潜在的副作用,并且在拖放时尝试落入没有输入焦点的应用程序窗口可能会出现潜在问题。 - wheels53
我们需要能够在任何地方拖动图像。我们想出的解决方案如下:RIA即Silverlight向我们的桌面应用程序WinForms发送一条消息,其中包含要拖动的图像路径以及我们希望从屏幕坐标开始拖动的边界矩形。桌面代码创建并放置一个面板,覆盖我们要从中拖动的区域。当用户左键单击时,我们使用DoDragDrop在此面板上启动本机拖动。由于此面板位于Silverlight控件之外且上方,因此一切都运作良好。沙箱被打败了。 - wheels53
显示剩余5条评论

2
我们想出的解决方案如下。RIA即Silverlight向我们的桌面应用程序WinForms发送一条消息,其中包括要拖动的图像路径以及我们希望从屏幕坐标开始拖动的边界矩形。桌面代码创建并放置一个面板,覆盖我们希望从中拖动的区域。当用户左键单击时,在此面板上使用DoDragDrop启动本地拖动。由于此面板位于Silverlight控件之外且在其上方,所以一切都运行完美。沙箱被打败了。

所以你已经有一个适用于你的应用程序的设置了?听起来不错。我想你一定能够想出办法来解决问题。 - Adam Jones
我正在为同样的问题苦苦挣扎。我的当前配置涉及Silverlight浏览器内部更新。在此期间,当MouseDown时,我建立了一个套接字连接(也许以后我会找到更好/更简单的协议-这只是第一个有效的协议),连接到另一个独立的WinForms应用程序。响应连接后调用自己的DoDragDrop。但是,d'n'd会话没有任何反馈,而且相当不可预测。我认为这与在浏览器中MouseDown时调用DoDragDrop有关。您能否提供更多详细信息(可能是来源)? - Adam Badura
我会把一些源代码片段放在一起,但可能需要几天时间,因为我写那段代码已经很久了。我相信关键因素是在光标下方放置一个带有传递屏幕坐标的窗体面板,然后在该面板内执行dodragdrop操作。 - wheels53
我试过了。 我也尝试在窗体上移动光标,但没有帮助。(即使窗体声称左键已按下。) 似乎问题在于一旦在 Silverlight(ListBox 项)上按下按钮,鼠标就被“盗取”或类似的东西...... 我尝试激活窗体(Activate();),我尝试捕获鼠标(Capture = true;),但都无济于事。 感谢您的支持! - Adam Badura

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接