首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在MacOS上使用DataObject (拖放文件)

如何在MacOS上使用DataObject (拖放文件)
EN

Stack Overflow用户
提问于 2018-06-09 05:45:09
回答 1查看 365关注 0票数 1

DataObject是System.Windows的一部分,在Xamarin.Mac中不可用。那么我该如何解决这个问题呢?我想创建一个带有外部文件的拖放函数。在Windows上,我可以用DataObject来做到这一点。

我已经寻找了替代方案,用NSUrl尝试了一下,但没有成功。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-09 06:22:51

拖到您的应用程序中:

所有基于NSView的类都有一个RegisterForDraggedTypes方法,您可以传递您想要接受的内容(在本例中,您向应用程序传递内容时是一个UTType.FileURL,假设是来自Finder的文件)。

所以在本例中,我有一个NSTableView,它接受文件,将它们添加到表中,并触发一个通知,使NSTask处理它们(这是一个基于FFMPEG的任务)。

tableView.RegisterForDraggedTypes(new string[] { UTType.FileURL };

从那里开始,它取决于您要拖入的NSView的类型,但是以NSTableView为例,您可以为其数据委托分配一个NSTableViewDataSource子类,您已经覆盖了ValidateDropAcceptDrop

NSTableViewDataSource.ValidateDrop中,您可以确认拖放是否包含您将接受的文件。在这种情况下,只要它是我接受的任何类型的文件:

public override NSDragOperation ValidateDrop(NSTableView tableView, NSDraggingInfo info, nint row, NSTableViewDropOperation dropOperation)
{
    var operation = NSDragOperation.Copy;
    using (var pasteBoard = info.DraggingPasteboard)
    {
        foreach (var item in pasteBoard.PasteboardItems)
        {
            if (!item.Types.Contains(UTType.FileURL))
            {
                operation = NSDragOperation.None;
            }
            item.Dispose();
        }
    }
    return operation;
}

NSTableViewDataSource.AcceptDrop中,您实际上是从drop中处理文件。

public override bool AcceptDrop(NSTableView tableView, NSDraggingInfo info, nint row, NSTableViewDropOperation dropOperation)
{
    using (var pasteBoard = info.DraggingPasteboard)
    {
        if (pasteBoard.PasteboardItems.Length > 0)
        {
            var range = new NSRange(-1, 0);
            foreach (var item in pasteBoard.PasteboardItems)
            {
                if (item.Types.Contains(UTType.FileURL))
                {
                    var finderNode = item.GetStringForType(UTType.FileURL);
                    // you have a file from macOS' finder, do something with it, assumable in a table view you would add a record/row....

                    var url = NSUrl.FromString(finderNode);
                    // url has the file extension, filename, full path, etc...

                   Post a notification / Add a task to GCD / etc...
                }
                item.Dispose();
            }
            return true;
        }
    }
    return false;
}

拖出你的应用程序:

假设您有一个Finder子类,您希望将一个“文件”拖出或拖入NSView或任何接受文件拖放的应用程序。在NSView子类上实现接口:INSDraggingSourceINSPasteboardItemDataProvider

MouseDown事件中,开始拖动UTType.FileURL类型:

public override void MouseDown(NSEvent theEvent)
{
    var pasteboardItem = new NSPasteboardItem();
    pasteboardItem.SetDataProviderForTypes(this, new string[1] { UTType.FileURL });

    var draggingItem = new NSDraggingItem(pasteboardItem);
    var fileDragIcon = new NSImage("theDraggingIcon.png");
    draggingItem.SetDraggingFrame(new CoreGraphics.CGRect(0,0,40,40), fileDragIcon);
    BeginDraggingSession(new NSDraggingItem[1] { draggingItem }, theEvent, this);
}

ProvideDataForType中,将文件url放到粘贴板上:

public void ProvideDataForType(NSPasteboard pasteboard, NSPasteboardItem item, string type)
{
    if (type == UTType.FileURL )
    {
        var url = new NSUrl("/Users/Sushi/Desktop/StackOverflow.png", false);
        url.WriteToPasteboard(pasteboard);
    }
}

注意:这只是传输文件的一种方式,还有其他三种文件拖动传输,您也可以提供一组urls,承诺稍后自己创建文件,并将文件的数据实际插入到粘贴板中。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50768769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档