C#WinForms:标识拖放操作事件的类型
用例:用户需要能够将电子邮件项目从Outlook拖放到我的WinForms(.Net 4)应用程序中的表单上。应用程序以.msg格式保存这些项目,并将其存储在预定位置 问题:我的代码对来自其他源的拖放不稳定(例如,将jpeg从IE拖到表单上会触发相同的事件)。这是因为我无法确定拖动的项目是否是Outlook对象,或者拖动的项目来自哪个源 是否有一种解决方法,使我只能接受特定类型的拖放项?以下是我在DragDrop事件处理程序中的代码:C#WinForms:标识拖放操作事件的类型,c#,winforms,drag-and-drop,C#,Winforms,Drag And Drop,用例:用户需要能够将电子邮件项目从Outlook拖放到我的WinForms(.Net 4)应用程序中的表单上。应用程序以.msg格式保存这些项目,并将其存储在预定位置 问题:我的代码对来自其他源的拖放不稳定(例如,将jpeg从IE拖到表单上会触发相同的事件)。这是因为我无法确定拖动的项目是否是Outlook对象,或者拖动的项目来自哪个源 是否有一种解决方法,使我只能接受特定类型的拖放项?以下是我在DragDrop事件处理程序中的代码: Outlook.Application outlook =
Outlook.Application outlook = new Outlook.Application();
Outlook.Selection sel = outlook.ActiveExplorer().Selection;
try
{
foreach (object item in sel)
{
if (item is Outlook.MailItem)
{
var mail = item as Outlook.MailItem;
CopyMailItemToLocalTempDir(mail);
txtComment.Text = "Email from " + mail.SenderName + " Regarding " + mail.Subject;
}
}
}
finally
{
// This is hokey but it prevents Outlook from remembering previously selected items
// - refer http://stackoverflow.com/questions/14090420/interop-outlook-doesnt-clear-selected-mails-at-drag-and-drop
var folder = outlook.ActiveExplorer().CurrentFolder;
outlook.ActiveExplorer().CurrentFolder = outlook.GetNamespace("MAPI").GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
Thread.Sleep(50);
outlook.ActiveExplorer().CurrentFolder = folder;
Marshal.ReleaseComObject(sel);
Marshal.ReleaseComObject(outlook);
sel = null;
outlook = null;
}
从Outlook拖动时有关DragEventArgs对象(e)的一些详细信息:
e.Data.GetFormats() returns:
{string[15]}
[0]: "RenPrivateSourceFolder"
[1]: "RenPrivateLatestMessages"
[2]: "RenPrivateMessages"
[3]: "RenPrivateItem"
[4]: "FileGroupDescriptor"
[5]: "FileGroupDescriptorW"
[6]: "FileDrop"
[7]: "FileNameW"
[8]: "FileName"
[9]: "FileContents"
[10]: "Object Descriptor"
[11]: "System.String"
[12]: "UnicodeText"
[13]: "Text"
[14]: "CSV"
e.Data.GetData("Text") returns:
"From\tSubject\tReceived\tSize\tCategories\t\r\nJoe Sender\tThis is the email subject\t10:51 AM\t3 KB\t\t"
我这里有只允许删除outlook项目的解决方案的源代码。以下是事件处理程序:
private void Form1_DragEnter(object sender, DragEventArgs e)
{
//display formats available
this.label1.Text = "Formats:\n";
foreach (string format in e.Data.GetFormats())
{
this.label1.Text += " " + format + "\n";
}
//ensure FileGroupDescriptor is present before allowing drop
if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
e.Effect = DragDropEffects.All;
}
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
//wrap standard IDataObject in OutlookDataObject
OutlookDataObject dataObject = new OutlookDataObject(e.Data);
//get the names and data streams of the files dropped
string[] filenames = (string[])dataObject.GetData("FileGroupDescriptorW");
MemoryStream[] filestreams = (MemoryStream[])dataObject.GetData("FileContents");
this.label1.Text += "Files:\n";
for (int fileIndex = 0; fileIndex < filenames.Length; fileIndex++)
{
//use the fileindex to get the name and data stream
string filename = filenames[fileIndex];
MemoryStream filestream = filestreams[fileIndex];
this.label1.Text += " " + filename + "\n";
//save the file stream using its name to the application path
FileStream outputStream = File.Create(filename);
filestream.WriteTo(outputStream);
outputStream.Close();
}
}
private void Form1\u DragEnter(对象发送方,DragEventArgs e)
{
//可用的显示格式
this.label1.Text=“格式:\n”;
foreach(e.Data.GetFormats()中的字符串格式)
{
this.label1.Text+=“”+格式+“\n”;
}
//在允许删除之前,请确保FileGroupDescriptor存在
if(例如Data.GetDataPresent(“FileGroupDescriptor”))
{
e、 效果=DragDropEffects.All;
}
}
私有无效表单1_DragDrop(对象发送方,DragEventArgs e)
{
//在OutlookDataObject中包装标准IDataObject
OutlookDataObject数据对象=新的OutlookDataObject(即数据);
//获取已删除文件的名称和数据流
字符串[]文件名=(字符串[])dataObject.GetData(“FileGroupDescriptorW”);
MemoryStream[]filestreams=(MemoryStream[])dataObject.GetData(“FileContents”);
this.label1.Text+=“文件:\n”;
对于(int fileIndex=0;fileIndex
是否有一种变通方法,使我只能接受
特殊类型
是的,有两条路
(处理单个文件时):
及
关于健壮性
由于您没有指定类型为Outlook.MailItem
(或者可能是Image
),但是源代码:我假设您的程序在代码的其他部分失败(由于设计不好)。例如,ActiveExplorer()。在第二行或finally{}
部分中选择。通过预筛选/尝试就地捕获(在涉及outlook之前)或在DragEnter
事件中捕获(当类型严格为某种outlook类型时更好),这很容易管理
要掌握拖放功能
用于多文件处理
或者对于outlook消息这样的特殊类型,您已经有了一个很好的解决方案,其中有很多解释
我还发现(2012年写的)展示了OutlookDataObject类,可能是基于您提到的文章(2008年写的)。FileGroupDescriptor或FileGroupDescriptorW的存在是否意味着Outlook是源代码?还有其他应用程序可以拥有相同的属性吗?我不知道,但这是你必须在谷歌上搜索的东西。我的例子对你有用吗?看起来你的例子需要外部代码。。。OutlookDataObject?仍然没有找到我问题的确切答案,但这篇文章最接近:
if (e.Data.GetData(typeof(...)) is ...)
//process it
if (e.Data.GetDataPresent(typeof(...)))
//process it