4

この挨拶のウェブサイトでの私の最初の投稿です。私は経験豊富なC#、. Net、Monoユーザーですが、MonoMacのNoobは、NSViewでフォルダーを受け取り、そのパスを使用してフォルダー内のファイルを処理するアプリを作成しようとしています...

MonoMacフレームワークは実装していませんdraggingEntered:, draggingUpdated:, draggingExited:, prepareForDragOperation:, performDragOperation:, concludeDragOperation: and draggingEnded:

だから私はそれらを自分で実装しようとしました:

[Register("TargetView")] 
public class TargetView:NSView
{
    private static IntPtr selDraggingEntered = Selector.GetHandle ("draggingEntered:");

    private static IntPtr selDraggingUpdated = Selector.GetHandle ("draggingUpdated:");

    private static IntPtr selDraggingExited = Selector.GetHandle ("draggingExited:");

    private static IntPtr selPrepareForDragOperation = Selector.GetHandle ("prepareForDragOperation:");

    private static IntPtr selPerformDragOperation = Selector.GetHandle ("performDragOperation:");

    private static IntPtr selConcludeDragOperation = Selector.GetHandle ("concludeDragOperation:");

    private static IntPtr selDraggingEnded = Selector.GetHandle ("draggingEnded:");

    public TargetView():base(){
    }

    public TargetView(NSCoder coder):base(coder){
    }

    public TargetView(NSObjectFlag t):base(t){
    }

    public TargetView(IntPtr handle):base(handle){
    }

    public TargetView(RectangleF frameRect):base(frameRect){
    }

    [Export ("draggingEntered:")]
    public virtual NSDragOperation DraggingEntered (NSDraggingInfo sender)
    {
        if (sender == null)
        {
            throw new ArgumentNullException ("sender");
        }
        if (this.IsDirectBinding)
        {
            return (NSDragOperation)Messaging.int_objc_msgSend_int (base.Handle, TargetView.selDraggingEntered, (int)sender.DraggingSourceOperationMask);
        }
        return (NSDragOperation)Messaging.int_objc_msgSendSuper_int (base.Handle, TargetView.selDraggingEntered, (int)sender.DraggingSourceOperationMask);
    }

    [Export ("draggingUpdated:")]
    public virtual NSDragOperation DraggingUpdated (NSDraggingInfo sender)
    {
        if (sender == null)
        {
            throw new ArgumentNullException ("sender");
        }
        if (this.IsDirectBinding)
        {
            return (NSDragOperation)Messaging.int_objc_msgSend_int (base.Handle, TargetView.selDraggingUpdated, (int)sender.DraggingSourceOperationMask);
        }
        return (NSDragOperation)Messaging.int_objc_msgSendSuper_int (base.Handle, TargetView.selDraggingUpdated, (int)sender.DraggingSourceOperationMask);
    }

    [Export ("draggingExited:")]
    public virtual void DraggingExited (NSDraggingInfo sender)
    {
        if (sender == null)
        {
            throw new ArgumentNullException ("sender");
        }
        if (this.IsDirectBinding)
        {
            Messaging.void_objc_msgSend_int (base.Handle, TargetView.selDraggingExited, (int)sender.DraggingSourceOperationMask);
        }
        Messaging.void_objc_msgSendSuper_int (base.Handle, TargetView.selDraggingExited, (int)sender.DraggingSourceOperationMask);
    }

    [Export ("prepareForDragOperation:")]
    public virtual bool PrepareForDragOperation (NSDraggingInfo sender)
    {
        if (sender == null)
        {
            throw new ArgumentNullException ("sender");
        }
        if (this.IsDirectBinding)
        {
            return Messaging.bool_objc_msgSend_int (base.Handle, TargetView.selPrepareForDragOperation, (int)sender.DraggingSourceOperationMask);
        }
        return Messaging.bool_objc_msgSendSuper_int (base.Handle, TargetView.selPrepareForDragOperation, (int)sender.DraggingSourceOperationMask);
    }

    [Export ("performDragOperation:")]
    public virtual bool PerformDragOperation (NSDraggingInfo sender)
    {
        if (sender == null)
        {
            throw new ArgumentNullException ("sender");
        }
        if (this.IsDirectBinding)
        {
            return Messaging.bool_objc_msgSend_int (base.Handle, TargetView.selPerformDragOperation, (int)sender.DraggingSourceOperationMask);
        }
        return Messaging.bool_objc_msgSendSuper_int (base.Handle, TargetView.selPerformDragOperation, (int)sender.DraggingSourceOperationMask);
    }

    [Export ("concludeDragOperation:")]
    public virtual void ConcludeDragOperation (NSDraggingInfo sender)
    {
        if (sender == null)
        {
            throw new ArgumentNullException ("sender");
        }
        if (this.IsDirectBinding)
        {
            Messaging.void_objc_msgSend_int (base.Handle, TargetView.selConcludeDragOperation, (int)sender.DraggingSourceOperationMask);
        }
        Messaging.void_objc_msgSendSuper_int (base.Handle, TargetView.selConcludeDragOperation, (int)sender.DraggingSourceOperationMask);
    }

    [Export ("draggingEnded:")]
    public virtual void DraggingEnded (NSDraggingInfo sender)
    {
        if (sender == null)
        {
            throw new ArgumentNullException ("sender");
        }
        if (this.IsDirectBinding)
        {
            Messaging.void_objc_msgSend_int (base.Handle, TargetView.selDraggingEnded, (int)sender.DraggingSourceOperationMask);
        }
        Messaging.void_objc_msgSendSuper_int (base.Handle, TargetView.selDraggingEnded, (int)sender.DraggingSourceOperationMask);
    }
}

しかし、メソッドは呼び出されません!

私もしようとしましRegisterForDraggedTypesたが、型として文字列配列に何を渡すのかわかりません!

私がそれを理解するのを手伝ってください。私は今グーグルで48を検索しています!

4

2 に答える 2

7

いくつかのテストを行い、それらをドラッグアンドドロップセッションのAppleドキュメントと比較することで、私はついに自分の質問に対する答えを見つけました。

これが私が使用したソースであり、それは魅力のような世界です:

[Register("DropTargetView")]
public class DropTargetView:NSView
{
    public DropTargetView(IntPtr handle):base(handle){

        RegisterForDraggedTypes(new string[]{"NSFilenamesPboardType"});
    }

    [Export ("draggingEntered:")]
    public NSDragOperation DraggingEntered (NSDraggingInfo sender)
    {
        NSPasteboard pasteboard = sender.DraggingPasteboard;

        bool typeExists = (Array.IndexOf(pasteboard.Types,"NSFilenamesPboardType") >= 0);

        if(typeExists)
        {
            return NSDragOperation.Link;
        }
        else
        {
            return NSDragOperation.None;
        }
    }

    [Export ("performDragOperation:")]
    public bool PerformDragOperation (NSDraggingInfo sender)
    {
        NSPasteboard pasteboard = sender.DraggingPasteboard;

        bool typeExists = (Array.IndexOf(pasteboard.Types,"NSFilenamesPboardType") >= 0);

        if(typeExists)
        {
            NSPasteboardItem[] pasteboardItems = pasteboard.PasteboardItems;

            for(int i = 0; i < pasteboardItems.Length; i++)
            {
                string urlStr = pasteboardItems[i].GetStringForType("public.file-url");

                NSUrl url = new NSUrl (urlStr);

                string filePath = url.Path;

                Console.WriteLine(filePath);
            }

            return true;
        }
        else
        {
            return false;
        }
    }
}

ここに少し説明があります:

CustomクラスがHandleを使用してインスタンス化されていることを最初に理解したので、そのメソッドにRegisterForDraggedTypesを登録する必要がありました。次に、Appleのドキュメントのサンプルを使用して、RegisterForDraggedTypes文字列constをトレースし、そこから「RegisterForDraggedTypes」を取り出して、ファイルのパスの登録値として使用しました。そして、Appleのドキュメントのサンプルを使用すると、エクスポートする必要があるのはdraggingEntered:とperformDragOperation:の2つのメソッドだけであることがわかりました。そのため、Cocoaにメッセージを送信して値を返すのではなく、自分でエクスポートして期待値を返しました。 。NSPasteboardItemsからファイルURLを抽出するために必要なUTIは、「public.file-url」として定義されたUTI Appleであるため、次の形式でパスを取得するために使用しました。

file:// localhost / PathToFileOrFolder /FileOrFolderName[/フォルダーの場合]

それが他の誰かを助けることを願っています。

更新(2015-09-30):

@M_Kで言及されている変更をコードに適用しました。

于 2012-03-14T10:30:23.153 に答える
0

pasteboardItems[i].GetStringForType("public.file-url")最新バージョンのMonoMac/Xamarinでは、ファイルパスの代わりにを呼び出すと、次のURLが返されることに気付きました。

file:///。file / id=..。

ファイルパスを取得するには、次のようにする必要があります。

string urlStr = pasteboardItems[i].GetStringForType("public.file-url");
NSUrl url = new NSUrl (urlStr);
string filePath = url.Path;
于 2015-09-23T05:14:46.217 に答える