From Q102850:
"Hi,
I am using the FileAttachmentBase to add files to a class in my project. Drag/Drop works great if I want to add a file from Windows Explorer. I want to be able to drag an attachment from Outlook and drop it into my application in the same way.
Thanks,
Stephan"
FileAttachments Module - How to drag & drop file attachments from Outlook messages into ListView or DetailView with FileData objects
Answers approved by DevExpress Support
Hello, Michael!
We investigated your code and introduced a few changes to XAF codebase to make your implementation simpler.
Starting with version 17.2.5 (try this hot fix build, if you cannot wait for the next maintenance build), you can handle the FileAttachmentListViewController.CustomDragOver event to manually set the e.DragEventErgs.Effect property to DragDropEffects.Copy for the "FileGroupDescriptor" data format and handle the FileAttachmentListViewController.CustomizeDragDropFileNames event to manually save messages to temporary files and specify names for created files:
C#using DragAndDropEmailFileAttachment.Module.BusinessObjects;
using System.IO;
using Microsoft.Office.Interop.Outlook;
using System.Windows.Forms;
using System.Linq;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.FileAttachments.Win;
namespace DragAndDropEmailFileAttachment.Module.Win.Controllers
{
public class DragDropAttachmentsFromEmailController : ViewController
{
private FileAttachmentListViewController fileAttachmentListViewController;
public DragDropAttachmentsFromEmailController() : base() {
TargetViewType = ViewType.ListView;
TargetObjectType = typeof(ObjectWithAttachment);
}
protected override void OnActivated() {
base.OnActivated();
fileAttachmentListViewController = Frame.GetController<FileAttachmentListViewController>();
if (fileAttachmentListViewController != null) {
fileAttachmentListViewController.CustomDragOver += FileAttachmentListViewController_CustomDragOver;
fileAttachmentListViewController.CustomizeDragDropFileNames += FileAttachmentListViewController_CustomizeDragDropFileNames;
}
}
private void FileAttachmentListViewController_CustomDragOver(object sender, CustomDragOverEventArgs e) {
if(fileAttachmentListViewController != null && fileAttachmentListViewController.AddFromFileAction.Active) {
if(e.DragEventArgs.Data.GetDataPresent(DataFormats.FileDrop)) {
e.DragEventArgs.Effect = DragDropEffects.Copy;
}
else if(e.DragEventArgs.Data.GetDataPresent("FileGroupDescriptor")) {
e.DragEventArgs.Effect = DragDropEffects.Copy;
}
else {
e.DragEventArgs.Effect = DragDropEffects.None;
}
}
else {
e.DragEventArgs.Effect = DragDropEffects.None;
}
e.Handled = true;
}
private string CorrectFileName(string fileName) {
foreach(char invalidChar in Path.GetInvalidFileNameChars()) {
if(fileName.Contains(invalidChar)) {
fileName = fileName.Replace(invalidChar, '_');
}
}
return fileName;
}
private void FileAttachmentListViewController_CustomizeDragDropFileNames(object sender, CustomizeDragDropFileNamesEventArgs e) {
if(e.DragEventArgs.Data.GetDataPresent("FileGroupDescriptor")) {
Microsoft.Office.Interop.Outlook.Application outlookApplication = new Microsoft.Office.Interop.Outlook.Application();
foreach(MailItem mailItem in outlookApplication.ActiveExplorer().Selection.OfType<MailItem>()) {
string fileName = mailItem.Subject + ".msg";
fileName = CorrectFileName(fileName);
string fullFileName = Path.Combine(Path.GetTempPath(), this.Application.ApplicationName, "tempmsgs", fileName);
mailItem.SaveAs(fullFileName, OlSaveAsType.olMSG);
e.FileNames.Add(fullFileName);
}
}
}
protected override void OnDeactivated() {
base.OnDeactivated();
if (fileAttachmentListViewController != null) {
fileAttachmentListViewController.CustomizeDragDropFileNames -= FileAttachmentListViewController_CustomizeDragDropFileNames;
fileAttachmentListViewController.CustomDragOver -= FileAttachmentListViewController_CustomDragOver;
fileAttachmentListViewController = null;
}
}
}
}
See the attached project for more details.
Additional references:
How to: Install the Visual Studio Tools for Office Runtime Redistributable
Referencing the Office Primary Interop Assembly
Cannot find Microsoft.Office.Interop Visual Studio
Thanks,
Nat.
Hello, Michael!
These events will be available starting with version 17.2.5.
Thanks,
Nat
Other Answers
Here is a quick solution with inheritance.
I save the msg file to the temp folder and load it into the fileattachment class.
namespace Salud.Module.Win.Controllers
{
public partial class OutlookMsgDragnDropController : DevExpress.ExpressApp.FileAttachments.Win.FileAttachmentListViewController
{
public OutlookMsgDragnDropController()
{
InitializeComponent();
}
protected void GetOutlookMessage(DragEventArgs e)
{
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
for (int i = 1; i <= oApp.ActiveExplorer().Selection.Count; i++)
{
object temp = oApp.ActiveExplorer().Selection[i];
if (temp is Microsoft.Office.Interop.Outlook.MailItem)
{
Microsoft.Office.Interop.Outlook.MailItem mailItem = (temp as Microsoft.Office.Interop.Outlook.MailItem);
string file = string.Format(@"{0}{1}.msg", Path.Combine(Path.GetTempPath(), "YourTempFolder"), mailItem.Subject.Replace(":","-"));
mailItem.SaveAs(file, Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG);
//Load msg file into your byte array
Dateianhang datei = FileHelper.LoadFromFile(ObjectSpace, file, "Email");
//Add to collection
((DevExpress.ExpressApp.ListView)View).CollectionSource.Add(datei);
ObjectSpace.CommitChanges();
}
}
}
protected override void OnDragDrop(DragEventArgs e)
{
if (e.Data.GetDataPresent("FileGroupDescriptor"))
GetOutlookMessage(e);
else
base.OnDragDrop(e);
}
protected override void OnDragOver(DragEventArgs e)
{
if (AddFromFileAction.Active && e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
else if (e.Data.GetDataPresent("FileGroupDescriptor"))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
}
}
Recommendations for XAF v17.2.4 and older versions
Hello Randy,
I would like to repost my solution from the T182151 ticket for you and others to follow. In fact, it does not require our source code modification and can be implemented on your project side after disabling the default class:
1. Copy the content of the …\DevExpress.ExpressApp.Modules\DevExpress.ExpressApp.FileAttachment.Win\FileAttachmentListViewController.cs file into your project. This class does not contain a lot of code and uses only public and documented APIs. It should not be difficult to maintain this class.
2. Change the default namespace and class name to yours and add the following method into the copied class:
Codeprotected override void OnFrameAssigned() {
base.OnFrameAssigned();
Frame.GetController<DevExpress.ExpressApp.FileAttachments.Win.FileAttachmentListViewController>().Active["any text"] = false;
}
3. Modify its source code as you require to support drag-and-drop operations from Outlook messages. The latter part is unrelated to DevExpress, and you may want to look for standard solutions on sites like StackOverFlow, CodeProject, MSDN, etc. For instance, the https://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C article or VB.NET example code in the T252167 ticket looks like a good starting point.
NOTE: this WinForms solution is for ListView, but a similar solution can be implemented for the FilePropertyEditor and its underlying FileDataEdit in DetailView. You may need to create a custom property editor based on the FileDataEdit descendant with the overridden OnDragDrop and OnDragOver methods (refer to the corresponding XAF source code for more details).
ASP.NET WebForms solutions will be different due to the underlying platform specifics. We also suggest you first implement this task in a non-XAF form first. The following tickets will be a good starting point for this:
Would the creator of ticket https://supportcenter.devexpress.com/ticket/details/q466771 which is linked above mind to open it as public ticket?
@Andreas: While we cannot make q466771 public, I have updated my original answer with the links to relevant ASP.NET WebForms examples.
Is this any closer to being implemented?
@Rafik: This feature is not yet planned for any specific release.
thumbs up
I would appreciate this Feature too. Several customers asked for it already.
This is not a XAF specific issue. Please search the web for solutions.
I have just received specific user request for this feature as well. Reading other related tickets, it seems the only option is to modify and recompile DevExpress sources - not something I want to do.
Before I head down a long and treacherous path is there any update on whether this will be supported by the fileattachment module? Either dragging the email OR dragging the attachments from the email? Currently users are getting around this by saving the MSG or attachments first, but since they know about drag/drop from File Explorer they can't understand why they can do this from Outlook as well.
I am familiar with handling this as a fully custom option (did it years ago in Visual Foxpro drag/drop on a grid from either file or Outlook item) and it worked beautiful. However, since we are already using the fileattachment and the filesystemdata modifications (to store on disk vs. database) I would like to be able to extend or override the drag/drop behavior without modifying sources.