Share via


Xamarin.Mac에서 복사하여 붙여넣기

이 문서에서는 붙여넣기를 사용하여 Xamarin.Mac 애플리케이션에 복사 및 붙여넣기를 제공하는 방법을 설명합니다. 여러 앱 간에 공유할 수 있는 표준 데이터 형식을 사용하는 방법과 지정된 앱 내에서 사용자 지정 데이터를 지원하는 방법을 보여 줍니다.

개요

Xamarin.Mac 애플리케이션에서 C# 및 .NET으로 작업하는 경우 작업 중인 개발자와 동일한 붙여넣기(복사 및 붙여넣기) 지원에 액세스할 수 있습니다 Objective-C .

이 문서에서는 Xamarin.Mac 앱에서 붙여넣기를 사용하는 두 가지 기본 방법을 설명합니다.

  1. 표준 데이터 형식 - 일반적으로 두 개의 관련 없는 앱 간에 붙여넣기 작업이 수행되므로 두 앱 모두 다른 앱이 지원하는 데이터 형식을 알지 못합니다. 공유 가능성을 최대화하기 위해 붙여넣기는 지정된 항목의 여러 표현(일반 데이터 형식의 표준 집합 사용)을 보유할 수 있습니다. 이렇게 하면 소비 앱이 요구 사항에 가장 적합한 버전을 선택할 수 있습니다.
  2. 사용자 지정 데이터 - Xamarin.Mac 내에서 복잡한 데이터의 복사 및 붙여넣기를 지원하려면 붙여넣기에서 처리할 사용자 지정 데이터 형식을 정의할 수 있습니다. 예를 들어 사용자가 여러 데이터 형식 및 요소로 구성된 복잡한 셰이프를 복사하여 붙여넣을 수 있는 벡터 그리기 앱이 있습니다.

실행 중인 앱의 예

이 문서에서는 복사 및 붙여넣기 작업을 지원하기 위해 Xamarin.Mac 애플리케이션에서 붙여넣기 작업의 기본 사항을 설명합니다. 이 문서에서 사용할 주요 개념과 기술을 다루므로 Hello, Mac 문서, 특히 Xcode 및 인터페이스 작성기 및 콘센트 및 작업 소개 섹션을 통해 작업하는 것이 좋습니다.

Xamarin.Mac Internals 문서의 섹션Objective-C대한 C# 클래스/메서드 노출을 살펴보고 C# 클래스 Objective-C 를 개체 및 UI 요소에 연결하는 데 사용되는 특성과 Export 특성을 설명 Register 합니다.

붙여넣기 시작

붙여넣기에서는 지정된 애플리케이션 내에서 또는 애플리케이션 간에 데이터를 교환하기 위한 표준화된 메커니즘을 제공합니다. Xamarin.Mac 애플리케이션에서 붙여넣기를 사용하는 일반적인 용도는 복사 및 붙여넣기 작업을 처리하는 것입니다. 그러나 여러 다른 작업도 지원됩니다(예: 끌어서 놓기 및 Application Services).

빠르게 시작하려면 Xamarin.Mac 앱에서 붙여넣기 사용을 간단하고 실용적인 소개로 시작하겠습니다. 나중에 붙여넣기의 작동 방식과 사용된 메서드에 대한 자세한 설명을 제공합니다.

이 예제에서는 이미지 보기가 포함된 창을 관리하는 간단한 문서 기반 애플리케이션을 만듭니다. 사용자는 앱의 문서와 동일한 앱 내의 다른 앱 또는 여러 창 간에 이미지를 복사하여 붙여넣을 수 있습니다.

Xamarin 프로젝트 만들기

먼저 복사 및 붙여넣기 지원을 추가할 새 문서 기반 Xamarin.Mac 앱을 만듭니다.

다음을 수행하십시오:

  1. Mac용 Visual Studio 시작하고 새 프로젝트... 링크를 클릭합니다.

  2. Mac>앱>Cocoa 앱을 선택한 다음, 다음 단추를 클릭합니다.

    새 Cocoa 앱 프로젝트 만들기

  3. 프로젝트 이름을 입력 MacCopyPaste 하고 다른 모든 항목을 기본값으로 유지합니다. 다음:

    프로젝트 이름 설정

  4. 만들기 단추를 클릭합니다.

    새 프로젝트 설정 확인

NSDocument 추가

다음으로 애플리케이션의 사용자 인터페이스에 대한 백그라운드 스토리지 역할을 하는 사용자 지정 NSDocument 클래스를 추가합니다. 여기에는 단일 이미지 뷰가 포함되며 뷰에서 기본 붙여넣기로 이미지를 복사하는 방법과 기본 붙여넣기에서 이미지를 가져와 이미지 보기에 표시하는 방법을 알고 있습니다.

Solution Pad에서 Xamarin.Mac 프로젝트를 마우스 오른쪽 단추로 클릭하고 새 파일 추가>를 선택합니다.

프로젝트에 NSDocument 추가

이름에 대해 ImageDocument를 입력하고 새로 만들기 단추를 클릭합니다. ImageDocument.cs 클래스를 편집하고 다음과 같이 표시합니다.

using System;
using AppKit;
using Foundation;
using ObjCRuntime;

namespace MacCopyPaste
{
    [Register("ImageDocument")]
    public class ImageDocument : NSDocument
    {
        #region Computed Properties
        public NSImageView ImageView {get; set;}

        public ImageInfo Info { get; set; } = new ImageInfo();

        public bool ImageAvailableOnPasteboard {
            get {
                // Initialize the pasteboard
                NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
                Class [] classArray  = { new Class ("NSImage") };

                // Check to see if an image is on the pasteboard
                return pasteboard.CanReadObjectForClasses (classArray, null);
            }
        }
        #endregion

        #region Constructor
        public ImageDocument ()
        {
        }
        #endregion

        #region Public Methods
        [Export("CopyImage:")]
        public void CopyImage(NSObject sender) {

            // Grab the current image
            var image = ImageView.Image;

            // Anything to process?
            if (image != null) {
                // Get the standard pasteboard
                var pasteboard = NSPasteboard.GeneralPasteboard;

                // Empty the current contents
                pasteboard.ClearContents();

                // Add the current image to the pasteboard
                pasteboard.WriteObjects (new NSImage[] {image});

                // Save the custom data class to the pastebaord
                pasteboard.WriteObjects (new ImageInfo[] { Info });

                // Using a Pasteboard Item
                NSPasteboardItem item = new NSPasteboardItem();
                string[] writableTypes = {"public.text"};

                // Add a data provier to the item
                ImageInfoDataProvider dataProvider = new ImageInfoDataProvider (Info.Name, Info.ImageType);
                var ok = item.SetDataProviderForTypes (dataProvider, writableTypes);

                // Save to pasteboard
                if (ok) {
                    pasteboard.WriteObjects (new NSPasteboardItem[] { item });
                }
            }

        }

        [Export("PasteImage:")]
        public void PasteImage(NSObject sender) {

            // Initialize the pasteboard
            NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
            Class [] classArray  = { new Class ("NSImage") };

            bool ok = pasteboard.CanReadObjectForClasses (classArray, null);
            if (ok) {
                // Read the image off of the pasteboard
                NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray, null);
                NSImage image = (NSImage)objectsToPaste[0];

                // Display the new image
                ImageView.Image = image;
            }

            Class [] classArray2 = { new Class ("ImageInfo") };
            ok = pasteboard.CanReadObjectForClasses (classArray2, null);
            if (ok) {
                // Read the image off of the pasteboard
                NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray2, null);
                ImageInfo info = (ImageInfo)objectsToPaste[0];

            }

        }
        #endregion
    }
}

아래 코드 중 일부를 자세히 살펴보겠습니다.

다음 코드는 이미지를 사용할 수 true 있는 경우 기본 붙여넣기에서 이미지 데이터가 있는지 테스트하는 속성을 제공합니다. 그렇지 않으면 false반환됩니다.

public bool ImageAvailableOnPasteboard {
    get {
        // Initialize the pasteboard
        NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
        Class [] classArray  = { new Class ("NSImage") };

        // Check to see if an image is on the pasteboard
        return pasteboard.CanReadObjectForClasses (classArray, null);
    }
}

다음 코드는 연결된 이미지 보기의 이미지를 기본 붙여넣기에 복사합니다.

[Export("CopyImage:")]
public void CopyImage(NSObject sender) {

    // Grab the current image
    var image = ImageView.Image;

    // Anything to process?
    if (image != null) {
        // Get the standard pasteboard
        var pasteboard = NSPasteboard.GeneralPasteboard;

        // Empty the current contents
        pasteboard.ClearContents();

        // Add the current image to the pasteboard
        pasteboard.WriteObjects (new NSImage[] {image});

        // Save the custom data class to the pastebaord
        pasteboard.WriteObjects (new ImageInfo[] { Info });

        // Using a Pasteboard Item
        NSPasteboardItem item = new NSPasteboardItem();
        string[] writableTypes = {"public.text"};

        // Add a data provider to the item
        ImageInfoDataProvider dataProvider = new ImageInfoDataProvider (Info.Name, Info.ImageType);
        var ok = item.SetDataProviderForTypes (dataProvider, writableTypes);

        // Save to pasteboard
        if (ok) {
            pasteboard.WriteObjects (new NSPasteboardItem[] { item });
        }
    }

}

그리고 다음 코드는 기본 붙여넣기에서 이미지를 붙여넣고 첨부된 이미지 보기에 표시합니다(붙여넣기 보드에 유효한 이미지가 포함된 경우).

[Export("PasteImage:")]
public void PasteImage(NSObject sender) {

    // Initialize the pasteboard
    NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
    Class [] classArray  = { new Class ("NSImage") };

    bool ok = pasteboard.CanReadObjectForClasses (classArray, null);
    if (ok) {
        // Read the image off of the pasteboard
        NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray, null);
        NSImage image = (NSImage)objectsToPaste[0];

        // Display the new image
        ImageView.Image = image;
    }

    Class [] classArray2 = { new Class ("ImageInfo") };
    ok = pasteboard.CanReadObjectForClasses (classArray2, null);
    if (ok) {
        // Read the image off of the pasteboard
        NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray2, null);
        ImageInfo info = (ImageInfo)objectsToPaste[0]
    }
}

이 문서를 사용하여 Xamarin.Mac 앱에 대한 사용자 인터페이스를 만듭니다.

사용자 인터페이스 빌드

Main.storyboard 파일을 두 번 클릭하여 Xcode에서 엽니다. 다음으로 도구 모음과 이미지를 잘 추가하고 다음과 같이 구성합니다.

도구 모음 편집

복사본을 추가하고 도구 모음의 왼쪽에 이미지 도구 모음 항목을 붙여넣습니다. 편집 메뉴에서 복사하여 붙여넣기 위한 바로 가기로 사용할 예정입니다. 다음으로, 도구 모음의 오른쪽에 4개의 이미지 도구 모음 항목을 추가합니다. 이러한 이미지를 사용하여 일부 기본 이미지로 이미지를 잘 채울 것입니다.

도구 모음 작업에 대한 자세한 내용은 도구 모음 설명서를 참조하세요.

다음으로 도구 모음 항목 및 이미지에 대해 다음과 같은 콘센트 및 작업을 노출해 보겠습니다.

콘센트 및 작업 만들기

콘센트 및 작업 작업에 대한 자세한 내용은 Hello, Mac 설명서의 콘센트 및 작업 섹션을 참조하세요.

사용자 인터페이스 사용

Xcode에서 만든 사용자 인터페이스와 콘센트 및 작업을 통해 노출된 UI 요소를 사용하여 UI를 사용하도록 설정하는 코드를 추가해야 합니다. Solution Pad에서 ImageWindow.cs 파일을 두 번 클릭하고 다음과 같이 표시합니다.

using System;
using Foundation;
using AppKit;

namespace MacCopyPaste
{
    public partial class ImageWindow : NSWindow
    {
        #region Private Variables
        ImageDocument document;
        #endregion

        #region Computed Properties
        [Export ("Document")]
        public ImageDocument Document {
            get {
                return document;
            }
            set {
                WillChangeValue ("Document");
                document = value;
                DidChangeValue ("Document");
            }
        }

        public ViewController ImageViewController {
            get { return ContentViewController as ViewController; }
        }

        public NSImage Image {
            get {
                return ImageViewController.Image;
            }
            set {
                ImageViewController.Image = value;
            }
        }
        #endregion

        #region Constructor
        public ImageWindow (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void AwakeFromNib ()
        {
            base.AwakeFromNib ();

            // Create a new document instance
            Document = new ImageDocument ();

            // Attach to image view
            Document.ImageView = ImageViewController.ContentView;
        }
        #endregion

        #region Public Methods
        public void CopyImage (NSObject sender)
        {
            Document.CopyImage (sender);
        }

        public void PasteImage (NSObject sender)
        {
            Document.PasteImage (sender);
        }

        public void ImageOne (NSObject sender)
        {
            // Load image
            Image = NSImage.ImageNamed ("Image01.jpg");

            // Set image info
            Document.Info.Name = "city";
            Document.Info.ImageType = "jpg";
        }

        public void ImageTwo (NSObject sender)
        {
            // Load image
            Image = NSImage.ImageNamed ("Image02.jpg");

            // Set image info
            Document.Info.Name = "theater";
            Document.Info.ImageType = "jpg";
        }

        public void ImageThree (NSObject sender)
        {
            // Load image
            Image = NSImage.ImageNamed ("Image03.jpg");

            // Set image info
            Document.Info.Name = "keyboard";
            Document.Info.ImageType = "jpg";
        }

        public void ImageFour (NSObject sender)
        {
            // Load image
            Image = NSImage.ImageNamed ("Image04.jpg");

            // Set image info
            Document.Info.Name = "trees";
            Document.Info.ImageType = "jpg";
        }
        #endregion
    }
}

아래에서 이 코드를 자세히 살펴보겠습니다.

먼저 위에서 만든 클래스의 인스턴스를 ImageDocument 노출합니다.

private ImageDocument _document;
...

[Export ("Document")]
public ImageDocument Document {
    get { return _document; }
    set {
        WillChangeValue ("Document");
        _document = value;
        DidChangeValue ("Document");
    }
}

를 사용하여 ExportWillChangeValueDidChangeValueXcode에서 Document 키-값 코딩 및 데이터 바인딩을 허용하도록 속성을 설정했습니다.

또한 다음 속성을 사용하여 Xcode의 UI에 추가한 이미지 웰의 이미지를 노출합니다.

public ViewController ImageViewController {
    get { return ContentViewController as ViewController; }
}

public NSImage Image {
    get {
        return ImageViewController.Image;
    }
    set {
        ImageViewController.Image = value;
    }
}

주 창이 로드되고 표시되면 클래스의 ImageDocument 인스턴스를 만들고 다음 코드를 사용하여 UI의 이미지를 잘 연결합니다.

public override void AwakeFromNib ()
{
    base.AwakeFromNib ();

    // Create a new document instance
    Document = new ImageDocument ();

    // Attach to image view
    Document.ImageView = ImageViewController.ContentView;
}

마지막으로 사용자가 복사하여 도구 모음 항목을 붙여넣는 것에 대한 응답으로 클래스 인스턴스 ImageDocument 를 호출하여 실제 작업을 수행합니다.

partial void CopyImage (NSObject sender) {
    Document.CopyImage(sender);
}

partial void PasteImage (Foundation.NSObject sender) {
    Document.PasteImage(sender);
}

파일 및 편집 메뉴 사용

마지막으로 해야 할 일은 파일 메뉴에서 새 메뉴 항목을 사용하도록 설정하고(기본 창의 새 인스턴스를 만들기 위해) 편집 메뉴에서 잘라내기, 복사붙여넣기 메뉴 항목을 사용하도록 설정하는 것입니다.

메뉴 항목을 사용하도록 설정하려면 AppDelegate.cs 파일을 편집하고 다음 코드를 추가합니다.

public int UntitledWindowCount { get; set;} =1;
...

[Export ("newDocument:")]
void NewDocument (NSObject sender) {
    // Get new window
    var storyboard = NSStoryboard.FromName ("Main", null);
    var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

    // Display
    controller.ShowWindow(this);

    // Set the title
    controller.Window.Title = (++UntitledWindowCount == 1) ? "untitled" : string.Format ("untitled {0}", UntitledWindowCount);
}

자세한 내용은 Windows 설명서의 여러 Windows 작업 섹션을 참조하세요.

잘라내기, 복사붙여넣기 메뉴 항목을 사용하도록 설정하려면 AppDelegate.cs 파일을 편집하고 다음 코드를 추가합니다.

[Export("copy:")]
void CopyImage (NSObject sender)
{
    // Get the main window
    var window = NSApplication.SharedApplication.KeyWindow as ImageWindow;

    // Anything to do?
    if (window == null)
        return;

    // Copy the image to the clipboard
    window.Document.CopyImage (sender);
}

[Export("cut:")]
void CutImage (NSObject sender)
{
    // Get the main window
    var window = NSApplication.SharedApplication.KeyWindow as ImageWindow;

    // Anything to do?
    if (window == null)
        return;

    // Copy the image to the clipboard
    window.Document.CopyImage (sender);

    // Clear the existing image
    window.Image = null;
}

[Export("paste:")]
void PasteImage (NSObject sender)
{
    // Get the main window
    var window = NSApplication.SharedApplication.KeyWindow as ImageWindow;

    // Anything to do?
    if (window == null)
        return;

    // Paste the image from the clipboard
    window.Document.PasteImage (sender);
}

각 메뉴 항목에 대해 현재, 최상위 키 창을 가져와서 클래스로 ImageWindow 캐스팅합니다.

var window = NSApplication.SharedApplication.KeyWindow as ImageWindow;

여기에서 해당 창의 클래스 인스턴스를 ImageDocument 호출하여 복사 및 붙여넣기 작업을 처리합니다. 예시:

window.Document.CopyImage (sender);

기본 붙여넣기 또는 현재 활성 창의 이미지 웰에 이미지 데이터가 있는 경우에만 잘라내기, 복사붙여넣기 메뉴 항목에 액세스할 수 있도록 합니다.

Xamarin.Mac 프로젝트에 EditMenuDelegate.cs 파일을 추가하고 다음과 같이 만들어 보겠습니다.

using System;
using AppKit;

namespace MacCopyPaste
{
    public class EditMenuDelegate : NSMenuDelegate
    {
        #region Override Methods
        public override void MenuWillHighlightItem (NSMenu menu, NSMenuItem item)
        {
        }

        public override void NeedsUpdate (NSMenu menu)
        {
            // Get list of menu items
            NSMenuItem[] Items = menu.ItemArray ();

            // Get the key window and determine if the required images are available
            var window = NSApplication.SharedApplication.KeyWindow as ImageWindow;
            var hasImage = (window != null) && (window.Image != null);
            var hasImageOnPasteboard = (window != null) && window.Document.ImageAvailableOnPasteboard;

            // Process every item in the menu
            foreach(NSMenuItem item in Items) {
                // Take action based on the menu title
                switch (item.Title) {
                case "Cut":
                case "Copy":
                case "Delete":
                    // Only enable if there is an image in the view
                    item.Enabled = hasImage;
                    break;
                case "Paste":
                    // Only enable if there is an image on the pasteboard
                    item.Enabled = hasImageOnPasteboard;
                    break;
                default:
                    // Only enable the item if it has a sub menu
                    item.Enabled = item.HasSubmenu;
                    break;
                }
            }
        }
        #endregion
    }
}

다시 말하지만, 현재 맨 위 창을 가져와서 해당 ImageDocument 클래스 인스턴스를 사용하여 필요한 이미지 데이터가 있는지 확인합니다. 그런 다음 이 메서드를 MenuWillHighlightItem 사용하여 이 상태에 따라 각 항목을 사용하거나 사용하지 않도록 설정합니다.

AppDelegate.cs 파일을 편집하고 메서드를 DidFinishLaunching 다음과 같이 표시합니다.

public override void DidFinishLaunching (NSNotification notification)
{
    // Disable automatic item enabling on the Edit menu
    EditMenu.AutoEnablesItems = false;
    EditMenu.Delegate = new EditMenuDelegate ();
}

먼저 편집 메뉴에서 메뉴 항목의 자동 사용 및 비활성화를 사용하지 않도록 설정합니다. 다음으로 위에서 만든 클래스의 인스턴스를 EditMenuDelegate 연결합니다.

자세한 내용은 메뉴 설명서를 참조하세요.

앱 테스트

모든 것이 준비되면 애플리케이션을 테스트할 준비가 된 것입니다. 앱을 빌드하고 실행하면 기본 인터페이스가 표시됩니다.

애플리케이션 실행

편집 메뉴를 열면 이미지 웰 또는 기본 붙여넣기에 이미지가 없으므로 잘라내기, 복사붙여 넣기를 사용할 수 없습니다.

편집 메뉴 열기

이미지 웰에 이미지를 추가하고 편집 메뉴를 다시 열면 이제 항목이 사용하도록 설정됩니다.

편집 메뉴 항목 표시가 활성화됨

이미지를 복사하고 파일 메뉴에서 새로 만들기를 선택하면 해당 이미지를 새 창에 붙여넣을 수 있습니다.

새 창에 이미지 붙여넣기

다음 섹션에서는 Xamarin.Mac 애플리케이션에서 붙여넣기 작업을 자세히 살펴보겠습니다.

붙여넣기 정보

macOS(이전의 OS X)에서 붙여넣기(NSPasteboard)는 복사 및 붙여넣기, 끌어서 놓기 및 Application Services와 같은 여러 서버 프로세스를 지원합니다. 다음 섹션에서는 몇 가지 주요 붙여넣기 개념을 자세히 살펴보겠습니다.

붙여넣기란?

이 클래스는 NSPasteboard 애플리케이션 간 또는 지정된 앱 내에서 정보를 교환하기 위한 표준화된 메커니즘을 제공합니다. 붙여넣기의 기본 함수는 복사 및 붙여넣기 작업을 처리하는 것입니다.

  1. 사용자가 앱에서 항목을 선택하고 잘라내기 또는 복사 메뉴 항목을 사용하는 경우 선택한 항목의 하나 이상의 표현이 붙여넣기판에 배치됩니다.
  2. 사용자가 같은 앱 또는 다른 앱 내에서 붙여넣기 메뉴 항목을 사용하는 경우 처리할 수 있는 데이터의 버전이 붙여넣기에서 복사되어 앱에 추가됩니다.

덜 명백한 붙여넣기 사용에는 찾기, 끌기, 끌어서 놓기 및 애플리케이션 서비스 작업이 포함됩니다.

  • 사용자가 끌기 작업을 시작하면 끌기 데이터가 붙여넣기 보드에 복사됩니다. 끌기 작업이 다른 앱에 대한 드롭으로 끝나는 경우 해당 앱은 붙여넣기에서 데이터를 복사합니다.
  • 번역 서비스의 경우 번역할 데이터는 요청 앱에 의해 붙여넣기판에 복사됩니다. 애플리케이션 서비스는 붙여넣기에서 데이터를 검색하고, 변환을 수행하고, 데이터를 붙여넣기 보드에 다시 붙여넣습니다.

가장 간단한 형식으로, 붙여넣기는 지정된 앱 내부 또는 앱 간에 데이터를 이동하는 데 사용되며, 따라서 앱 프로세스 외부의 특별한 전역 메모리 영역에 존재합니다. 붙여넣기의 개념은 쉽게 파악할 수 있지만 고려해야 할 몇 가지 더 복잡한 세부 사항이 있습니다. 아래에서 자세히 설명합니다.

명명된 붙여넣기

붙여넣기 보드는 퍼블릭 또는 프라이빗일 수 있으며 애플리케이션 내에서 또는 여러 앱 간에 다양한 용도로 사용할 수 있습니다. macOS는 몇 가지 표준 붙여넣기를 제공하며, 각각에는 잘 정의된 특정 사용법이 있습니다.

  • NSGeneralPboard- 잘라내기, 복사붙여넣기 작업의 기본 붙여넣기입니다.
  • NSRulerPboard- 눈금자에서 잘라내기, 복사붙여넣기 작업을 지원합니다.
  • NSFontPboard- 개체에 대한 NSFont 잘라내기, 복사붙여넣기 작업을 지원합니다.
  • NSFindPboard - 검색 텍스트를 공유할 수 있는 애플리케이션별 찾기 패널을 지원합니다.
  • NSDragPboard- 끌어서 놓기 작업을 지원합니다.

대부분의 경우 시스템 정의 붙여넣기 중 하나를 사용합니다. 그러나 사용자 고유의 붙여넣기를 만들어야 하는 상황이 있을 수 있습니다. 이러한 경우 클래스의 NSPasteboard 메서드를 FromName (string name) 사용하여 지정된 이름으로 사용자 지정 붙여넣기를 만들 수 있습니다.

필요에 따라 클래스의 메서드를 CreateWithUniqueNameNSPasteboard 호출하여 고유하게 명명된 붙여넣기를 만들 수 있습니다.

붙여넣기 항목

애플리케이션이 붙여넣기판에 쓰는 데이터의 각 조각은 붙여넣기 항목으로 간주되며 붙여넣기는 동시에 여러 항목을 보유할 수 있습니다. 이러한 방식으로 앱은 붙여넣기에 복사되는 데이터의 여러 버전(예: 일반 텍스트 및 서식이 지정된 텍스트)을 작성할 수 있으며 검색 앱은 처리할 수 있는 데이터만 읽을 수 있습니다(예: 일반 텍스트만 해당).

데이터 표현 및 균일한 형식 식별자

붙여넣기 작업은 일반적으로 서로에 대한 지식이 없는 두 개 이상의 애플리케이션 또는 각 애플리케이션이 처리할 수 있는 데이터 형식 간에 수행됩니다. 위의 섹션에서 설명한 대로 정보를 공유할 가능성을 최대화하기 위해 붙여넣기 보드에 복사 및 붙여넣는 데이터의 여러 표현이 저장될 수 있습니다.

각 표현은 표시되는 날짜의 형식을 고유하게 식별하는 간단한 문자열에 지나지 않는 UTI(Uniform Type Identifier)를 통해 식별됩니다(자세한 내용은 Apple의 Uniform Type Identifier 개요 설명서를 참조하세요).

사용자 지정 데이터 형식(예: 벡터 그리기 앱의 그리기 개체)을 만드는 경우 고유한 UTI를 만들어 복사 및 붙여넣기 작업에서 고유하게 식별할 수 있습니다.

앱이 붙여넣기에서 복사한 데이터를 붙여넣을 준비를 할 때 해당 능력에 가장 적합한 표현(있는 경우)을 찾아야 합니다. 일반적으로 이 형식은 사용 가능한 가장 풍부한 형식(예: 단어 처리 앱의 서식이 지정된 텍스트)이며, 필요에 따라 사용할 수 있는 가장 간단한 양식(단순 텍스트 편집기에 대한 일반 텍스트)으로 대체됩니다.

약속된 데이터

일반적으로 앱 간의 공유를 최대화하려면 복사되는 데이터의 표현을 최대한 많이 제공해야 합니다. 그러나 시간 또는 메모리 제약 조건으로 인해 각 데이터 형식을 실제로 붙여넣기에 쓰는 것은 실용적이지 않을 수 있습니다.

이 경우 첫 번째 데이터 표현을 붙여넣기 보드에 배치할 수 있으며, 수신 앱은 붙여넣기 작업 직전에 즉석에서 생성할 수 있는 다른 표현을 요청할 수 있습니다.

초기 항목을 붙여넣기 보드에 배치할 때 사용 가능한 다른 표현 중 하나 이상이 인터페이스를 준수하는 개체에 의해 제공되도록 지정합니다 NSPasteboardItemDataProvider . 이러한 개체는 수신 앱의 요청에 따라 요청 시 추가 표현을 제공합니다.

변경 횟수

각 붙여넣기 기본 새 소유자가 선언될 때마다 증가되는 변경 횟수를 포함합니다. 앱은 변경 횟수 값을 검사 마지막으로 검사한 이후 붙여넣기의 내용이 변경되었는지 확인할 수 있습니다.

클래스의 ChangeCount 메서드 및 ClearContents 메서드를 NSPasteboard 사용하여 지정된 붙여넣기의 변경 횟수를 수정합니다.

붙여넣기로 데이터 복사

먼저 붙여넣기 액세스, 기존 콘텐츠 지우기 및 붙여넣기에서 필요한 만큼 데이터 표현을 작성하여 복사 작업을 수행합니다.

예시:

// Get the standard pasteboard
var pasteboard = NSPasteboard.GeneralPasteboard;

// Empty the current contents
pasteboard.ClearContents();

// Add the current image to the pasteboard
pasteboard.WriteObjects (new NSImage[] {image});

일반적으로 위의 예제에서 수행한 것처럼 일반 붙여넣기만 작성합니다. 메서드에 보내는 모든 개체는 WriteObjects 인터페이스를 INSPasteboardWriting 준수해야 합니다. 여러 기본 제공 클래스(예: NSString, NSImage, NSURL, NSColorNSAttributedStringNSPasteboardItem)가 이 인터페이스를 자동으로 준수합니다.

붙여넣기에서 사용자 지정 데이터 클래스를 작성하는 경우 인터페이스를 준수 INSPasteboardWriting 하거나 클래스 인스턴스 NSPasteboardItem 에 래핑되어야 합니다(아래 사용자 지정 데이터 형식 섹션 참조).

붙여넣기에서 데이터 읽기

위에서 설명한 대로 앱 간에 데이터를 공유할 가능성을 최대화하기 위해 복사한 데이터의 여러 표현을 붙여넣기판에 쓸 수 있습니다. 해당 기능에 대해 가능한 가장 풍부한 버전을 선택하는 것은 수신 앱에 달려 있습니다(있는 경우).

간단한 붙여넣기 작업

메서드를 사용하여 붙여넣기에서 데이터를 읽습니다 ReadObjectsForClasses . 두 개의 매개 변수가 필요합니다.

  1. 붙여넣기에서 읽으려는 기반 클래스 형식의 배열 NSObject 입니다. 가장 원하는 데이터 형식으로 순서를 지정해야 하며, 다시 기본 형식은 기본 설정이 감소합니다.
  2. 추가 제약 조건이 포함된 사전(예: 특정 URL 콘텐츠 형식으로 제한) 또는 추가 제약 조건이 필요하지 않은 경우 빈 사전입니다.

이 메서드는 전달한 조건을 충족하는 항목 배열을 반환하므로 요청된 데이터 형식의 개수가 가장 같습니다. 요청된 형식이 없으며 빈 배열이 반환될 수도 있습니다.

예를 들어 다음 코드는 일반 붙여넣기판에 있는지 검사 NSImage 이미지에 잘 표시합니다.

[Export("PasteImage:")]
public void PasteImage(NSObject sender) {

    // Initialize the pasteboard
    NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
    Class [] classArray  = { new Class ("NSImage") };

    bool ok = pasteboard.CanReadObjectForClasses (classArray, null);
    if (ok) {
        // Read the image off of the pasteboard
        NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray, null);
        NSImage image = (NSImage)objectsToPaste[0];

        // Display the new image
        ImageView.Image = image;
    }

    Class [] classArray2 = { new Class ("ImageInfo") };
    ok = pasteboard.CanReadObjectForClasses (classArray2, null);
    if (ok) {
        // Read the image off of the pasteboard
        NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray2, null);
        ImageInfo info = (ImageInfo)objectsToPaste[0];
            }
}

여러 데이터 형식 요청

생성되는 Xamarin.Mac 애플리케이션의 형식에 따라 붙여넣을 데이터의 여러 표현을 처리할 수 있습니다. 이 경우 붙여넣기에서 데이터를 검색하는 두 가지 시나리오가 있습니다.

  1. 메서드를 한 번의 호출하고 ReadObjectsForClasses 원하는 모든 표현의 배열을 기본 순서로 제공합니다.
  2. 매번 다른 형식 배열을 ReadObjectsForClasses 요청하는 메서드를 여러 번 호출합니다.

붙여넣기 에서 데이터를 검색하는 방법은 위의 간단한 붙여넣기 작업 섹션을 참조하세요.

기존 데이터 형식 확인

붙여넣기에서 데이터를 실제로 읽지 않고 붙여넣기 보드에 지정된 데이터 표현이 포함된 경우(예: 유효한 데이터가 있을 때만 붙여넣기 메뉴 항목 사용) 검사 수 있습니다.

붙여넣기의 CanReadObjectForClasses 메서드를 호출하여 지정된 형식이 포함되어 있는지 확인합니다.

예를 들어 다음 코드는 일반 붙여넣기 보드에 인스턴스가 포함되어 있는지 확인합니다.NSImage

public bool ImageAvailableOnPasteboard {
    get {
        // Initialize the pasteboard
        NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
        Class [] classArray  = { new Class ("NSImage") };

        // Check to see if an image is on the pasteboard
        return pasteboard.CanReadObjectForClasses (classArray, null);
    }
}

붙여넣기에서 URL 읽기

지정된 Xamarin.Mac 앱의 함수에 따라 붙여넣기에서 URL을 읽어야 할 수 있지만 지정된 조건 집합(예: 특정 데이터 형식의 파일 또는 URL을 가리키는 것)을 충족하는 경우에만 필요합니다. 이 경우 또는 ReadObjectsForClasses 메서드의 CanReadObjectForClasses 두 번째 매개 변수를 사용하여 추가 검색 조건을 지정할 수 있습니다.

사용자 지정 데이터 유형

Xamarin.Mac 앱에서 사용자 지정 형식을 붙여넣기 보드에 저장해야 하는 경우가 있습니다. 예를 들어 사용자가 그리기 개체를 복사하여 붙여넣을 수 있는 벡터 그리기 앱이 있습니다.

이 경우 데이터 사용자 지정 클래스가 상속 NSObject 되고 몇 가지 인터페이스(INSCodingINSPasteboardWritingINSPasteboardReading)를 준수하도록 데이터 사용자 지정 클래스를 디자인해야 합니다. 필요에 따라 복사 NSPasteboardItem 하거나 붙여넣을 데이터를 캡슐화하는 데 사용할 수 있습니다.

이러한 두 옵션은 아래에서 자세히 설명합니다.

사용자 지정 클래스 사용

이 섹션에서는 이 문서의 시작 부분에서 만든 간단한 예제 앱을 확장하고 사용자 지정 클래스를 추가하여 복사하고 창 간에 붙여넣는 이미지에 대한 정보를 추적합니다.

프로젝트에 새 클래스를 추가하고 ImageInfo.cs 호출합니다. 파일을 편집하고 다음과 같이 표시합니다.

using System;
using AppKit;
using Foundation;

namespace MacCopyPaste
{
    [Register("ImageInfo")]
    public class ImageInfo : NSObject, INSCoding, INSPasteboardWriting, INSPasteboardReading
    {
        #region Computed Properties
        [Export("name")]
        public string Name { get; set; }

        [Export("imageType")]
        public string ImageType { get; set; }
        #endregion

        #region Constructors
        [Export ("init")]
        public ImageInfo ()
        {
        }

        public ImageInfo (IntPtr p) : base (p)
        {
        }

        [Export ("initWithCoder:")]
        public ImageInfo(NSCoder decoder) {

            // Decode data
            NSString name = decoder.DecodeObject("name") as NSString;
            NSString type = decoder.DecodeObject("imageType") as NSString;

            // Save data
            Name = name.ToString();
            ImageType = type.ToString ();
        }
        #endregion

        #region Public Methods
        [Export ("encodeWithCoder:")]
        public void EncodeTo (NSCoder encoder) {

            // Encode data
            encoder.Encode(new NSString(Name),"name");
            encoder.Encode(new NSString(ImageType),"imageType");
        }

        [Export ("writableTypesForPasteboard:")]
        public virtual string[] GetWritableTypesForPasteboard (NSPasteboard pasteboard) {
            string[] writableTypes = {"com.xamarin.image-info", "public.text"};
            return writableTypes;
        }

        [Export ("pasteboardPropertyListForType:")]
        public virtual NSObject GetPasteboardPropertyListForType (string type) {

            // Take action based on the requested type
            switch (type) {
            case "com.xamarin.image-info":
                return NSKeyedArchiver.ArchivedDataWithRootObject(this);
            case "public.text":
                return new NSString(string.Format("{0}.{1}", Name, ImageType));
            }

            // Failure, return null
            return null;
        }

        [Export ("readableTypesForPasteboard:")]
        public static string[] GetReadableTypesForPasteboard (NSPasteboard pasteboard){
            string[] readableTypes = {"com.xamarin.image-info", "public.text"};
            return readableTypes;
        }

        [Export ("readingOptionsForType:pasteboard:")]
        public static NSPasteboardReadingOptions GetReadingOptionsForType (string type, NSPasteboard pasteboard) {

            // Take action based on the requested type
            switch (type) {
            case "com.xamarin.image-info":
                return NSPasteboardReadingOptions.AsKeyedArchive;
            case "public.text":
                return NSPasteboardReadingOptions.AsString;
            }

            // Default to property list
            return NSPasteboardReadingOptions.AsPropertyList;
        }

        [Export ("initWithPasteboardPropertyList:ofType:")]
        public NSObject InitWithPasteboardPropertyList (NSObject propertyList, string type) {

            // Take action based on the requested type
            switch (type) {
            case "com.xamarin.image-info":
                return new ImageInfo();
            case "public.text":
                return new ImageInfo();
            }

            // Failure, return null
            return null;
        }
        #endregion
    }
}

다음 섹션에서는 이 클래스를 자세히 살펴보겠습니다.

상속 및 인터페이스

사용자 지정 데이터 클래스를 붙여넣기에서 쓰거나 읽을 수 있도록 하려면 먼저 해당 클래스와 INSPasteboardReading 인터페이스를 INSPastebaordWriting 준수해야 합니다. 또한 다음 인터페이스에서 NSObject 상속되고 인터페이스를 INSCoding 준수해야 합니다.

[Register("ImageInfo")]
public class ImageInfo : NSObject, INSCoding, INSPasteboardWriting, INSPasteboardReading
...

또한 클래스는 지시문을 사용하는 데 Objective-C 노출되어야 하며 , 을 Register 사용하여 Export필요한 속성 또는 메서드를 노출해야 합니다. 예시:

[Export("name")]
public string Name { get; set; }

[Export("imageType")]
public string ImageType { get; set; }

이미지의 이름과 형식(jpg, png 등)과 같이 이 클래스에 포함할 데이터의 두 필드를 노출합니다.

자세한 내용은 Xamarin.Mac Internals 설명서의 섹션에Objective-C대한 C# 클래스/메서드 노출을 참조하세요. C# 클래스를 개체 및 Export UI 요소에 연결하는 데 사용되는 특성 및 특성에 Objective-C 대해 설명 Register 합니다.

생성자

사용자 지정 데이터 클래스에 Objective-C두 개의 생성자(제대로 노출됨)가 필요하므로 붙여넣기에서 읽을 수 있습니다.

[Export ("init")]
public ImageInfo ()
{
}

[Export ("initWithCoder:")]
public ImageInfo(NSCoder decoder) {

    // Decode data
    NSString name = decoder.DecodeObject("name") as NSString;
    NSString type = decoder.DecodeObject("imageType") as NSString;

    // Save data
    Name = name.ToString();
    ImageType = type.ToString ();
}

먼저 , 의 기본 Objective-C 메서드 아래에 빈 생성자를 노출합니다init.

다음으로, 내보낸 이름 initWithCoder아래에 붙여넣을 때 붙여넣기에서 개체의 새 인스턴스를 만드는 데 사용할 규격 생성자를 공개 NSCoding 합니다.

이 생성자는 NSCoder (붙여넣기에서 작성할 때 만든 NSKeyedArchiver 대로) 키/값 쌍을 이루는 데이터를 추출하여 데이터 클래스의 속성 필드에 저장합니다.

붙여넣기에서 쓰기

인터페이스를 준수하여 클래스를 INSPasteboardWriting 붙여넣기판에 쓸 수 있도록 두 메서드와 선택적으로 세 번째 메서드를 노출해야 합니다.

먼저 사용자 지정 클래스를 쓸 수 있는 데이터 형식 표현을 붙여넣기 보드에 알려야 합니다.

[Export ("writableTypesForPasteboard:")]
public virtual string[] GetWritableTypesForPasteboard (NSPasteboard pasteboard) {
    string[] writableTypes = {"com.xamarin.image-info", "public.text"};
    return writableTypes;
}

각 표현은 표시되는 데이터의 형식을 고유하게 식별하는 간단한 문자열에 지나지 않는 UTI(Uniform Type Identifier)를 통해 식별됩니다(자세한 내용은 Apple의 Uniform Type Identifier 개요 설명서를 참조하세요).

사용자 지정 형식의 경우 자체 UTI인 "com.xamarin.image-info"를 만듭니다(앱 식별자처럼 역방향 표기법으로 표시됨). 또한 클래스는 붙여넣기(public.text)에 표준 문자열을 작성할 수 있습니다.

다음으로, 요청된 형식으로 개체를 만들어야 합니다. 이 형식은 실제로 붙여넣기판에 기록됩니다.

[Export ("pasteboardPropertyListForType:")]
public virtual NSObject GetPasteboardPropertyListForType (string type) {

    // Take action based on the requested type
    switch (type) {
    case "com.xamarin.image-info":
        return NSKeyedArchiver.ArchivedDataWithRootObject(this);
    case "public.text":
        return new NSString(string.Format("{0}.{1}", Name, ImageType));
    }

    // Failure, return null
    return null;
}

형식의 public.text 경우 서식이 지정된 간단한 개체를 NSString 반환합니다. 사용자 지정 형식의 경우 사용자 지정 com.xamarin.image-info 데이터 클래스를 NSKeyedArchiver 키/값 쌍으로 연결된 보관 파일로 인코딩하는 데 a와 NSCoder 인터페이스를 사용합니다. 인코딩을 실제로 처리하려면 다음 메서드를 구현해야 합니다.

[Export ("encodeWithCoder:")]
public void EncodeTo (NSCoder encoder) {

    // Encode data
    encoder.Encode(new NSString(Name),"name");
    encoder.Encode(new NSString(ImageType),"imageType");
}

개별 키/값 쌍은 인코더에 기록되며 위에서 추가한 두 번째 생성자를 사용하여 디코딩됩니다.

필요에 따라 다음 메서드를 포함하여 붙여넣기에서 데이터를 쓸 때 모든 옵션을 정의할 수 있습니다.

[Export ("writingOptionsForType:pasteboard:"), CompilerGenerated]
public virtual NSPasteboardWritingOptions GetWritingOptionsForType (string type, NSPasteboard pasteboard) {
    return NSPasteboardWritingOptions.WritingPromised;
}

현재는 옵션만 WritingPromised 사용할 수 있으며 지정된 형식만 약속되고 실제로 붙여넣기판에 기록되지 않은 경우에 사용해야 합니다. 자세한 내용은 위의 약속된 데이터 섹션을 참조하세요.

이러한 메서드를 사용하면 다음 코드를 사용하여 사용자 지정 클래스를 붙여넣기판에 쓸 수 있습니다.

// Get the standard pasteboard
var pasteboard = NSPasteboard.GeneralPasteboard;

// Empty the current contents
pasteboard.ClearContents();

// Add info to the pasteboard
pasteboard.WriteObjects (new ImageInfo[] { Info });

붙여넣기에서 읽기

인터페이스를 INSPasteboardReading 준수하여 사용자 지정 데이터 클래스를 붙여넣기에서 읽을 수 있도록 세 가지 메서드를 노출해야 합니다.

먼저 사용자 지정 클래스가 클립보드에서 읽을 수 있는 데이터 형식 표현을 붙여넣기 보드에 알려야 합니다.

[Export ("readableTypesForPasteboard:")]
public static string[] GetReadableTypesForPasteboard (NSPasteboard pasteboard){
    string[] readableTypes = {"com.xamarin.image-info", "public.text"};
    return readableTypes;
}

마찬가지로 이러한 항목은 간단한 요로로 정의되며 위의 붙여넣기 섹션에 쓰기 섹션에서 정의한 것과 동일한 형식입니다.

다음으로, 다음 메서드를 사용하여 각 UTI 형식을 읽는 방법을 붙여넣기 보드에 알려야 합니다.

[Export ("readingOptionsForType:pasteboard:")]
public static NSPasteboardReadingOptions GetReadingOptionsForType (string type, NSPasteboard pasteboard) {

    // Take action based on the requested type
    switch (type) {
    case "com.xamarin.image-info":
        return NSPasteboardReadingOptions.AsKeyedArchive;
    case "public.text":
        return NSPasteboardReadingOptions.AsString;
    }

    // Default to property list
    return NSPasteboardReadingOptions.AsPropertyList;
}

형식의 경우 클래스에 com.xamarin.image-info 추가한 생성자를 호출 initWithCoder: 하여 클래스를 붙여넣기판에 쓸 때 만든 NSKeyedArchiver 키/값 쌍을 디코딩하도록 붙여넣기를 지정합니다.

마지막으로 다음 메서드를 추가하여 붙여넣기에서 다른 UTI 데이터 표현을 읽어야 합니다.

[Export ("initWithPasteboardPropertyList:ofType:")]
public NSObject InitWithPasteboardPropertyList (NSObject propertyList, string type) {

    // Take action based on the requested type
    switch (type) {
    case "public.text":
        return new ImageInfo();
    }

    // Failure, return null
    return null;
}

이러한 모든 메서드를 사용하면 다음 코드를 사용하여 붙여넣기에서 사용자 지정 데이터 클래스를 읽을 수 있습니다.

// Initialize the pasteboard
NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
var classArrayPtrs = new [] { Class.GetHandle (typeof(ImageInfo)) };
NSArray classArray = NSArray.FromIntPtrs (classArrayPtrs);

// NOTE: Sending messages directly to the base Objective-C API because of this defect:
// https://bugzilla.xamarin.com/show_bug.cgi?id=31760
// Check to see if image info is on the pasteboard
ok = bool_objc_msgSend_IntPtr_IntPtr (pasteboard.Handle, Selector.GetHandle ("canReadObjectForClasses:options:"), classArray.Handle, IntPtr.Zero);

if (ok) {
    // Read the image off of the pasteboard
    NSObject [] objectsToPaste = NSArray.ArrayFromHandle<Foundation.NSObject>(IntPtr_objc_msgSend_IntPtr_IntPtr (pasteboard.Handle, Selector.GetHandle ("readObjectsForClasses:options:"), classArray.Handle, IntPtr.Zero));
    ImageInfo info = (ImageInfo)objectsToPaste[0];
}

NSPasteboardItem 사용

사용자 지정 클래스의 생성을 보증하지 않는 사용자 지정 항목을 붙여넣기 보드에 작성해야 하거나 필요에 따라 공통 형식으로 데이터를 제공하려는 경우가 있을 수 있습니다. 이러한 상황에서는 .를 사용할 NSPasteboardItem수 있습니다.

A NSPasteboardItem 는 붙여넣기로 작성되고 임시 액세스를 위해 설계된 데이터에 대한 세분화된 제어를 제공합니다. 이 데이터는 붙여넣기판에 기록된 후에 삭제해야 합니다.

데이터 쓰기

사용자 지정 데이터를 NSPasteboardItem 작성하려면 사용자 지정 NSPasteboardItemDataProvider을 제공해야 합니다. 프로젝트에 새 클래스를 추가하고 ImageInfoDataProvider.cs 호출합니다. 파일을 편집하고 다음과 같이 표시합니다.

using System;
using AppKit;
using Foundation;

namespace MacCopyPaste
{
    [Register("ImageInfoDataProvider")]
    public class ImageInfoDataProvider : NSPasteboardItemDataProvider
    {
        #region Computed Properties
        public string Name { get; set;}
        public string ImageType { get; set;}
        #endregion

        #region Constructors
        [Export ("init")]
        public ImageInfoDataProvider ()
        {
        }

        public ImageInfoDataProvider (string name, string imageType)
        {
            // Initialize
            this.Name = name;
            this.ImageType = imageType;
        }

        protected ImageInfoDataProvider (NSObjectFlag t){
        }

        protected internal ImageInfoDataProvider (IntPtr handle){

        }
        #endregion

        #region Override Methods
        [Export ("pasteboardFinishedWithDataProvider:")]
        public override void FinishedWithDataProvider (NSPasteboard pasteboard)
        {

        }

        [Export ("pasteboard:item:provideDataForType:")]
        public override void ProvideDataForType (NSPasteboard pasteboard, NSPasteboardItem item, string type)
        {

            // Take action based on the type
            switch (type) {
            case "public.text":
                // Encode the data to string
                item.SetStringForType(string.Format("{0}.{1}", Name, ImageType),type);
                break;
            }

        }
        #endregion
    }
}

사용자 지정 데이터 클래스와 마찬가지로, 및 Export 지시문을 사용하여 Register 해당 클래스를 노출해야 합니다Objective-C. 클래스는 상속 NSPasteboardItemDataProvider 해야 하며 메서드와 ProvideDataForType 메서드를 FinishedWithDataProvider 구현해야 합니다.

메서드를 ProvideDataForType 사용하여 다음과 같이 래핑 NSPasteboardItem 될 데이터를 제공합니다.

[Export ("pasteboard:item:provideDataForType:")]
public override void ProvideDataForType (NSPasteboard pasteboard, NSPasteboardItem item, string type)
{

    // Take action based on the type
    switch (type) {
    case "public.text":
        // Encode the data to string
        item.SetStringForType(string.Format("{0}.{1}", Name, ImageType),type);
        break;
    }

}

이 경우 이미지에 대한 두 가지 정보(이름 및 ImageType)를 저장하고 이를 간단한 문자열(public.text)에 기록합니다.

데이터를 붙여넣기판에 쓰는 형식으로 다음 코드를 사용합니다.

// Get the standard pasteboard
var pasteboard = NSPasteboard.GeneralPasteboard;

// Using a Pasteboard Item
NSPasteboardItem item = new NSPasteboardItem();
string[] writableTypes = {"public.text"};

// Add a data provider to the item
ImageInfoDataProvider dataProvider = new ImageInfoDataProvider (Info.Name, Info.ImageType);
var ok = item.SetDataProviderForTypes (dataProvider, writableTypes);

// Save to pasteboard
if (ok) {
    pasteboard.WriteObjects (new NSPasteboardItem[] { item });
}

데이터 읽기

붙여넣기에서 데이터를 다시 읽으려면 다음 코드를 사용합니다.

// Initialize the pasteboard
NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
Class [] classArray  = { new Class ("NSImage") };

bool ok = pasteboard.CanReadObjectForClasses (classArray, null);
if (ok) {
    // Read the image off of the pasteboard
    NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray, null);
    NSImage image = (NSImage)objectsToPaste[0];

    // Do something with data
    ...
}

Class [] classArray2 = { new Class ("ImageInfo") };
ok = pasteboard.CanReadObjectForClasses (classArray2, null);
if (ok) {
    // Read the image off of the pasteboard
    NSObject [] objectsToPaste = pasteboard.ReadObjectsForClasses (classArray2, null);

    // Do something with data
    ...
}

요약

이 문서에서는 복사 및 붙여넣기 작업을 지원하기 위해 Xamarin.Mac 애플리케이션에서 붙여넣기 작업을 자세히 살펴보았습니다. 먼저 표준 붙여넣기 작업에 익숙해지도록 하는 간단한 예제를 도입했습니다. 다음으로, 붙여넣기 및 해당 붙여넣기에서 데이터를 읽고 쓰는 방법을 자세히 살펴보았습니다. 마지막으로 사용자 지정 데이터 형식을 사용하여 앱 내에서 복잡한 데이터 형식의 복사 및 붙여넣기를 지원하는 방법을 살펴보았습니다.