我想从 Silverlight UIElement 中拖动图像并将其放在用户桌面或 Windows 资源管理器上

Posted

技术标签:

【中文标题】我想从 Silverlight UIElement 中拖动图像并将其放在用户桌面或 Windows 资源管理器上【英文标题】:I want to drag an image from a Silverlight UIElement and drop it on the users Desktop or Windows Explorer 【发布时间】:2011-11-02 08:37:09 【问题描述】:

我有一个包含图像的 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? 我们在表单中加载html和silverlight内容。 那么你使用的是WebBrowser控件吗? 是的。我们在 WebBrowser 控件中加载 html 和 Silverlight 插件。 【参考方案1】:

问题在于 Silverlight 中的拖动操作无法简单地访问浏览器之外的任何内容(根据设计)。根据用户的设置,您甚至必须获得剪贴板操作和沙盒临时文件存储的明确许可。这听起来确实像是更适合 WPF 应用程序(可能使用 web deployment?)或其他一些桌面应用程序技术的任务。

不过,这里说的是您可以尝试/考虑的一些事情:

    在 Internet Explorer 中托管的 Silverlight/javascript/ActiveX 组合 Silverlight 5“Out of Brower”和 P/Invoke(听说 Silverlight 5 推出后将支持 P/Invoke) Silverlight 连接到在同一台计算机上运行的 Web 服务(很疯狂,但您没有要求“不疯狂”,而是要求可能)

我对 Win32 API 中的拖放操作不是很熟悉,因此我需要进行大量研究和实验才能确认这甚至是可能的(我已经可以告诉你它不实用)。

编辑:根据您提供的有关该问题的额外信息,我怀疑可以做您正在尝试的事情。首先,您使用的是 WPF 还是 WinForms?我假设 WPF,但你的一个 cmets 说 WinForms。我对 WPF 拖放操作不是很熟悉,但是经过研究,我认为您的代码走在了正确的道路上。我创建了一个 WPF 应用程序并在 KeyDown 事件期间启动了拖动。这意味着不一定要按下鼠标按钮。如果我在按钮 按下时启动了DragDrop,它就起作用了。如果我在鼠标按钮没有按下时启动,我必须按下鼠标按钮并开始拖动操作(这是出乎意料的,因为我认为鼠标必须已经按下)。如果我在应用程序外按下鼠标,然后给 WPF 应用程序焦点(ALT+Tab),然后在鼠标按钮仍然按下时启动 DragDrop,它不起作用。我得到了MouseDevice 的引用并检查了LeftButton 属性,即使按钮仍被按住,状态仍显示为“已释放”。看来这里的关键是拖放与内部鼠标状态交互的方式。您可能必须找到一种方法来设置鼠标状态(也许使用 UI 自动化 API?)。在这一点上,很明显这整件事是一个 hack(尽管有可能让它以某种方式工作)。

【讨论】:

由于沙盒问题,我尝试在后面的代码中捕获鼠标左键按下事件。然后,我使用一些消息将图像文件路径发送到 WPF 桌面表单。在 WPF 表单中,我按如下方式初始化拖放。 代码见上面编辑过的帖子问题是拖动仍然没有初始化。 澄清。我们使用 WinForms 在 Windows 上托管我们的 Silverlight 插件。当 RIA 中发生 Left Mouse Down 事件时,会向主 Windows 窗体发送一条消息,其中包含要拖动的图像的绝对文件路径。在主窗体中,我使用原始帖子中指示的代码初始化拖动。我没有收到任何错误,但拖动不起作用。 有趣。我不得不承认我没有听说过有人在 WinForms 中托管 Silverlight。因此,您正在将数据发送到桌面应用程序,您是否尝试过以编程方式模拟/启动 MouseDown/MouseCapture,使其表现得就像在 WinForms 应用程序中启动了拖动一样?这可能允许您完成拖动操作。 也很高兴打破沙盒,你已经听起来比许多 Silverlight 开发人员更先进。 +1 跳出框框思考(完全是双关语)。 谢谢亚当。您能否提供一些示例代码来模拟 MouseDown/MouseCapture?【参考方案2】:

我们提出的解决方案如下。 RIA 即 Silverlight 向我们的桌面应用程序 WinForms 发送一条消息,其中包含要拖动的图像路径以及我们想要开始拖动的屏幕坐标中的边界矩形。桌面代码创建一个面板并将其放置在我们要从中拖动的区域上。这个面板是我们使用 DoDragDrop 在用户左键单击时启动本机拖动的地方。由于此面板放置在 Silverlight 控件的外部和上方,因此一切正常。沙盒被击败。

【讨论】:

所以你有一个适用于你的应用程序的设置是吗?听起来不错。我认为你可以解决一些问题。 我正在努力解决同样的问题。我当前的配置涉及浏览器内的 Silverlight。在 MouseDown 上,我设置了一个到另一个独立 WinForms 应用程序的套接字连接(也许稍后我会找到一个更好/更简单的协议 - 这只是第一个有效的协议)。响应连接调用它自己的DoDragDrop。然而,d'n'd 会议没有任何反馈,而且相当不可预测。我认为这与调用DoDragDrop 时在浏览器中按下鼠标有关。您能否提供解决方案的更多详细信息(可能是来源?)? 我会将一些源 sn-ps 放在一起,但可能需要几天时间,因为我已经很长时间没有编写该代码了。我相信关键因素是在光标下放置一个带有向下屏幕坐标的 win 表单面板,然后在该面板中执行 dodragdrop。 我试过了。我也尝试在表单上移动光标。它没有帮助。 (即使您表单声称左按钮已按下。)似乎问题在于,一旦在 Silverlight(ListBox 项)上按下按钮,鼠标就会以某种方式“被盗”或其他东西......我尝试激活表单(Activate(); ),我尝试捕获鼠标 (Capture = true;) 但没有任何帮助。感谢您的支持!【参考方案3】:

过去几个月我一直在开发一些 Silverlight 应用程序,并全面调查了您的确切要求,结果发现这是不可能的。我相信你可以从文件系统中拖动,从 Silverlight 控件拖动到控件,但不能拖动到文件系统。

Does Silverlight 4 support drag and drop from app to desktop?

http://msdn.microsoft.com/en-us/library/dd772166%28v=vs.95%29.aspx

【讨论】:

以上是关于我想从 Silverlight UIElement 中拖动图像并将其放在用户桌面或 Windows 资源管理器上的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Silverlight/WPF 中反转剪裁几何?

c#里面的slider控件怎么使用?求指点

从 ViewModel 触发 UIElement 的操作

背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性

背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性

WPF 自定义路由事件问题