Xamarin. Mac 'e Kopyala ve Yapıştır

Bu makalede, bir Xamarin. Mac uygulamasına kopyalama ve yapıştırma sağlamak için çalışma alanıyla çalışma alanı ele alınmaktadır. Birden çok uygulama arasında paylaşılabilen standart veri türleriyle çalışmayı ve belirli bir uygulama içindeki özel verileri desteklemeyi gösterir.

Genel Bakış

Bir Xamarin. Mac uygulamasında C# ve .NET ile çalışırken, üzerinde çalışan bir geliştiricinin sahip olduğu çalışma alanına (kopyalama ve yapıştırma) erişebilirsiniz Objective-C .

Bu makalede, bir Xamarin. Mac uygulamasında çalışma alanını kullanmanın iki ana yolu ele alınacaktır:

  1. Standart veri türleri -çalışma alanı işlemleri tipik olarak birbiriyle ilgisiz iki uygulama arasında yürütülür, ancak hiçbir uygulama diğer tarafından desteklenen veri türlerini bilir. Paylaşım potansiyelini en üst düzeye çıkarmak için, çalışma alanı belirli bir öğenin (Standart bir ortak veri türleri kümesi kullanılarak) birden çok temsilini tutabilir. Bu, tüketen uygulamanın, ihtiyaçlarına en uygun sürümü seçmesine izin verir.
  2. Özel veri -Xamarin. Mac 'inizde karmaşık verilerin kopyalanmasını ve yapıştırılmasını desteklemek için çalışma alanı tarafından işlenecek özel bir veri türü tanımlayabilirsiniz. Örneğin, kullanıcının birden çok veri türünden ve noktadan oluşan karmaşık şekilleri kopyalamasını ve yapıştırmasını sağlayan bir vektör çizim uygulaması.

Çalışan uygulamanınörneği örneği

Bu makalede, kopyalama ve yapıştırma işlemlerini desteklemek için bir Xamarin. Mac uygulamasındaki çalışma alanıyla çalışma alanının temelleri ele alınacaktır. Bu makalede kullanacağımız temel kavramları ve teknikleri kapsadığından, ilk olarak Hello, Mac makalesi, özellikle de xcode ve Interface Builder ve diğer ve eylemler bölümlerine giriş yapmanız önerilir.

Exposing C# classes / methods to Objective-CExposing C# classes / methods to Objective-C belgesinin bölümüne de göz atmak Isteyebilirsiniz, RegisterExport C# sınıflarınızı Objective-C nesneler ve Kullanıcı Arabirimi öğelerine bağlamak için kullanılan ve özniteliklerini açıklar.

Çalışma alanını kullanmaya başlama

Çalışma alanı, belirli bir uygulama içinde veya uygulamalar arasında veri değişimi için standartlaştırılmış bir mekanizma sunar. Xamarin. Mac uygulamasındaki çalışma alanının tipik kullanımı, kopyalama ve yapıştırma işlemlerini işleymaktır, ancak başka bir işlem de desteklenir (örneğin sürükle & bırak ve uygulama Hizmetleri).

Daha hızlı bir şekilde bir Xamarin. Mac uygulamasında pasteboards kullanmaya yönelik basit ve pratik bir giriş ile başlayacağız. Daha sonra, çalışma alanının nasıl çalıştığına ve kullanılan yöntemlere ilişkin derinlemesine bir açıklama sağlıyoruz.

Bu örnekte, bir görüntü görünümü içeren pencereyi yöneten basit bir belge tabanlı uygulama oluşturacağız. Kullanıcı, uygulama içindeki belgeler arasında ve diğer uygulamalardan veya aynı uygulamadaki birden çok pencere arasında görüntü kopyalayabilir ve yapıştırabilir.

Xamarin projesi oluşturma

İlk olarak, için kopyalama ve yapıştırma desteği ekleyeceğiz yeni bir belge tabanlı Xamarin. Mac uygulaması oluşturacağız.

Şunları yapın:

  1. Mac için Visual Studio başlatın ve yeni Project... bağlantısına tıklayın.

  2. MacuygulamasıCocoa uygulaması' nı seçin ve ardından İleri düğmesine tıklayın:

    Creating a new Cocoa app projectYeni bir projesi oluşturma projesi oluşturma

  3. MacCopyPasteMacCopyPaste için girin ve diğer her şeyi varsayılan olarak tutun. Ileri ' ye tıklayın:

    Setting the name of the projectProjenin adını

  4. Oluştur düğmesine tıklayın:

    Confirming the new project settingsYeni

NSDocument Ekle

Daha sonra NSDocument uygulamanın kullanıcı arabirimi için arka plan depolaması olarak davranacak özel bir sınıf ekleyeceğiz. Tek bir görüntü görünümü içerir ve görünümden bir görüntünün varsayılan çalışma alanına nasıl kopyalanacağını ve varsayılan çalışma alanından bir görüntünün nasıl alınacağını ve görüntünün görüntü görünümünde nasıl görüntüleneceğini öğrenirsiniz.

Çözüm bölmesi Xamarin. Mac projesine sağ tıklayın ve yeni dosya Ekle..: öğesini seçin.

Adding an NSDocument to the projectProjeye nsdocument ekleyerek

ImageDocumentImageDocument Için girin ve Yeni düğmesine tıklayın. Imagedocument. cs sınıfını düzenleyin ve aşağıdakine benzer şekilde görünür:

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
    }
}

Aşağıda ayrıntılı olarak bazı koda göz atalım.

Aşağıdaki kod, bir görüntü varsa, varsayılan çalışma alanındaki görüntü verilerinin varlığını test etmek için bir özellik sağlar truefalse :

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);
    }
}

Aşağıdaki kod, ekli görüntü görünümündeki bir görüntüyü varsayılan çalışma alanına kopyalar:

[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 });
        }
    }

}

Aşağıdaki kod, varsayılan çalışma alanındaki bir görüntüyü yapıştırır ve ekli görüntü görünümünde görüntüler (çalışma alanı geçerli bir görüntü içeriyorsa):

[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]
    }
}

Bu belge varken, Xamarin. Mac uygulamasının Kullanıcı arabirimini oluşturacağız.

Kullanıcı arabirimini oluşturma

Ana. görsel taslak dosyasına çift tıklayarak Xcode 'da açın. Sonra bir araç çubuğu ve bir görüntü kutusu ekleyin ve bunları şu şekilde yapılandırın:

Editing the toolbarAraç çubuğunu

Araç çubuğunun sol tarafına bir Kopyala ve Yapıştır görüntü araç çubuğu öğesi ekleyin. Düzenleme menüsünden kopyalamak ve yapıştırmak için kısayollar olarak kullanılacak. Sonra, araç çubuğunun sağ tarafına dört görüntü araç çubuğu öğesi ekleyin. Görüntüyü, bazı varsayılan görüntülerle birlikte doldurmak için kullanacağız.

Araç çubuklarıyla çalışma hakkında daha fazla bilgi için lütfen araç çubukları belgelerimize bakın.

Daha sonra, araç çubuğu öğelerimiz ve görüntü kutusu için aşağıdaki görevleri ve eylemleri sunalım:

Creating outlets and actionsAykırı izin

Dış ve eylemlerle çalışma hakkında daha fazla bilgi için lütfen Merhaba, Mac belgelerimizin ve eylemler bölümüne bakın.

Kullanıcı arabirimini etkinleştirme

Xcode 'da oluşturulan kullanıcı arabirimimiz ve işlemler ve eylemler aracılığıyla kullanıma sunulan UI öğesi sayesinde, Kullanıcı arabirimini etkinleştirmek için kodu eklememiz gerekir. Çözüm bölmesiımagewindow. cs dosyasına çift tıklayın ve aşağıdaki gibi görünmesini sağlayın:

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
    }
}

Aşağıda ayrıntılı olarak bu koda göz atalım.

İlk olarak, yukarıda oluşturduğumuz sınıfın bir örneğini kullanıma sunduk ImageDocument :

private ImageDocument _document;
...

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

Export, Ve kullanarak WillChangeValue , DidChangeValueDocument Xcode 'Da Key-Value kodlamaya ve veri bağlamaya izin vermek için özelliği kurduk.

Ayrıca, aşağıdaki özelliği kullanarak Xcode 'daki Kullanıcı arabirimimize eklediğimiz görüntünün görüntüsünü de kullanıma sunduk:

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

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

Ana pencere yüklenip görüntülenirken, sınıfınızın bir örneğini oluşturur ImageDocument ve Kullanıcı arabiriminin görüntüsünü aşağıdaki kodla birlikte ekleyin:

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

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

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

Son olarak, Kullanıcı, Kopyala ve Yapıştır araç çubuğu öğelerine tıklayarak, ImageDocument gerçek işi yapmak için sınıfının örneğini çağırdık:

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

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

Dosya ve düzenleme menülerini etkinleştirme

Yapmanız gereken son şey, Dosya menüsünden Yeni menü öğesini (ana penceremizin yeni örnekleri oluşturmak Için) etkinleştirir ve düzenleme menüsünden Kes, Kopyala ve Yapıştır menü öğelerini etkinleştirir.

Yeni menü öğesini etkinleştirmek Için appdelegate. cs dosyasını düzenleyin ve aşağıdaki kodu ekleyin:

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);
}

daha fazla bilgi için, Windows belgelerimizin birden çok Windows ile çalışma bölümüne bakın.

Kes, Kopyala ve Yapıştır menü öğelerini etkinleştirmek için appdelegate. cs dosyasını düzenleyin ve aşağıdaki kodu ekleyin:

[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);
}

Her menü öğesi için, geçerli, en üst ve anahtar pencereyi alır ve sınıfımızın üzerine atamalısınız ImageWindow :

var window = NSApplication.SharedApplication.KeyWindow as ImageWindow;

Buradan, ImageDocument Kopyala ve Yapıştır eylemlerini işlemek için söz konusu pencerenin sınıf örneğini çağırdık. Örnek:

window.Document.CopyImage (sender);

Varsayılan çalışma alanında veya geçerli etkin pencerenin görüntü kutusu 'nda görüntü verileri varsa, yalnızca kesme, kopyalama ve Yapıştırma menü öğelerini erişilebilir olacak şekilde istiyoruz.

Xamarin. Mac projesine bir Editmenudelegate. cs dosyası ekleyelim ve aşağıdaki gibi görünmesini sağlayın:

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
    }
}

Yine, geçerli, en üstteki pencereyi alır ve ImageDocument gerekli görüntü verilerinin mevcut olup olmadığını görmek için sınıf örneğini kullanır. Daha sonra MenuWillHighlightItem Bu duruma göre her bir öğeyi etkinleştirmek veya devre dışı bırakmak için yöntemini kullanırız.

Appdelegate. cs dosyasını düzenleyin ve yöntemin aşağıdaki gibi görünmesini sağlayın:

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

İlk olarak, düzenleme menüsünde menü öğelerinin otomatik olarak etkinleştirilmesini ve devre dışı bırakılmasını devre dışı bırakacağız. Daha sonra, EditMenuDelegate yukarıda oluşturduğumuz sınıfın bir örneğini ekliyoruz.

Daha fazla bilgi için lütfen menüler belgelerimize bakın.

Uygulamayı test etme

Her şey, uygulamayı test etmeye hazırız. Uygulamayı derleyin ve çalıştırın ve ana arabirim görüntülenir:

Uygulamayı çalıştıran

Düzen menüsünü açarsanız, görüntü kutusu içinde veya varsayılan çalışma alanında resim bulunmadığından Kes, Kopyala ve Yapıştır devre dışı bırakılır:

Opening the Edit menuDüzen menüsünü için

Görüntüye iyi bir görüntü ekler ve düzenleme menüsünü yeniden açarsanız, öğeler artık etkinleştirilecek:

Showing the Edit menu items are enabledDüzenle menü öğelerinin için

Görüntüyü kopyalayıp Dosya menüsünden Yeni ' yi seçerseniz, bu görüntüyü yeni pencereye yapıştırabilirsiniz:

Birgörüntüyü yeni yeni bir pencereye yapıştırma

Aşağıdaki bölümlerde, Xamarin. Mac uygulamasındaki çalışma alanıyla çalışmaya ilişkin ayrıntılı bir bakış ele alacağız.

Çalışma alanı hakkında

MacOS (eski adıyla OS X) içinde, çalışma alanı ( NSPasteboard ) kopyalama & yapıştırma, sürükleyip bırakma ve uygulama hizmetleri gibi çeşitli sunucu işlemlerine yönelik destek sağlar & . Aşağıdaki bölümlerde birkaç anahtar çalışma alanı kavramına daha yakından bakacağız.

Çalışma alanı nedir?

NSPasteboardSınıfı, uygulamalar arasında veya belirli bir uygulama içinde bilgi değişimi için standartlaştırılmış bir mekanizma sağlar. Çalışma alanının ana işlevi, kopyalama ve yapıştırma işlemlerini işlemeye yöneliktir:

  1. Kullanıcı uygulamada bir öğe seçtiğinde ve Kes veya Kopyala menü öğesini kullandığında, seçili öğenin bir veya daha fazla temsili çalışma alanına yerleştirilir.
  2. Kullanıcı Yapıştır menü öğesini (aynı uygulama veya farklı bir öğe içinde) kullandığında, işleyebileceği verilerin sürümü çalışma alanından kopyalanır ve uygulamaya eklenir.

Daha az belirgin çalışma alanı, bulma, sürükleme, sürükleme ve bırakma ve uygulama hizmetleri işlemlerini içerir:

  • Kullanıcı bir sürükleme işlemi başlattığında, sürükle verileri çalışma alanına kopyalanır. Sürükleme işlemi başka bir uygulamaya bir bırak ile sona ererse, bu uygulama verileri çalışma alanından kopyalar.
  • Çeviri Hizmetleri için çevrilecek veriler, istenen uygulama tarafından çalışma alanına kopyalanır. Uygulama Hizmeti, çalışma alanındaki verileri alır, çeviri yapar ve sonra verileri çalışma alanına geri yapıştırır.

En basit biçimlerinde, pasteboards belirli bir uygulama veya uygulamalar arasında verileri, uygulamanın işlemi dışındaki özel bir genel bellek alanında taşımak için kullanılır. Pasteboards kavramlarını kolayca Grasa da, göz önünde bulundurmanız gereken birkaç karmaşık ayrıntı vardır. Bunlar aşağıda ayrıntılı olarak ele alınacaktır.

Pasteboards adlı

Bir çalışma alanı herkese açık veya özel olabilir ve bir uygulama içindeki veya birden çok uygulama arasında çeşitli amaçlarla kullanılabilir. macOS, her biri belirli ve iyi tanımlanmış bir kullanıma sahip birkaç standart pasteboards sağlar:

  • NSGeneralPboard - NSGeneralPboard, kopyalama ve Yapıştırma işlemleri için varsayılan çalışma alanı.
  • NSRulerPboard- CetvellerdeNSRulerPboard, kopyalama ve Yapıştırma işlemlerini destekler.
  • NSFontPboard -Nesnelerde NSFontPboard, kopyalama ve Yapıştırma işlemlerini destekler .
  • NSFindPboard -Arama metnini paylaşabilen uygulamaya özgü bulma panellerini destekler.
  • NSDragPboard - NSDragPboard işlemlerini destekler.

Çoğu durumda, sistem tarafından tanımlanan pasteboards birini kullanacaksınız. Ancak kendi pasteboards oluşturmanızı gerektiren durumlar olabilir. Bu durumlarda, FromName (string name)NSPasteboard Verilen ada sahip özel bir çalışma alanı oluşturmak için sınıfının yöntemini kullanabilirsiniz.

İsteğe bağlı olarak, CreateWithUniqueNameNSPasteboard benzersiz olarak adlandırılmış bir çalışma alanı oluşturmak için sınıfının metodunu çağırabilirsiniz.

Çalışma alanı öğeleri

Bir uygulamanın çalışma alanına yazdığı her veri parçası, çalışma alanı öğesi olarak kabul edilir ve bir çalışma alanı aynı anda birden çok öğeyi tutabilir. Bu şekilde, bir uygulama, çalışma alanına Kopyalanmakta olan verilerin birden çok sürümünü yazabilir (örneğin, düz metin ve biçimlendirilen metin) ve alma uygulaması yalnızca işleyedikleri verileri (yalnızca düz metin gibi) okuyabilir.

Veri gösterimleri ve tek biçimli tür tanımlayıcıları

Çalışma alanı işlemleri tipik olarak, birbirleriyle ilgili bilgi içermeyen iki (veya daha fazla) uygulama veya her birinin işleyebileceği veri türleri arasında gerçekleşir. Yukarıdaki bölümde belirtildiği gibi, bilgi paylaşımı potansiyelini en üst düzeye çıkarmak için, bir çalışma alanı Kopyalanmakta olan ve yapıştırılan verilerin birden fazla temsilini tutabilir.

Her gösterim, sunulmakta olan tarih türünü benzersiz bir şekilde tanımlayan bir basit dizeden daha fazla olmayan bir Tekdüzen tür tanımlayıcısı (UTI) aracılığıyla tanımlanır (daha fazla bilgi için bkz. Apple 'ın Tekdüzen tür tanımlayıcılarına genel bakış belgeleri).

Özel bir veri türü oluşturuyorsanız (örneğin, bir vektör çizim uygulamasında bir çizim nesnesi), kopyalama ve yapıştırma işlemlerinde benzersiz şekilde tanımlamak için kendi UTı 'nizi oluşturabilirsiniz.

Bir uygulama çalışma alanından kopyalanmış verileri yapıştırmaya hazırlanırken, kendi yeteneklerine en uygun olan temsili (varsa) bulmalıdır. Genellikle bu, en basit formlara (örneğin, bir sözcük işleme uygulaması için biçimlendirilen metin) geri dönerek gerekli olan en basit formlara (basit bir metin Düzenleyicisi için düz metin) geri dönerek kullanılabilir.

Taahhüt edilen veriler

Genellikle, uygulamalar arasında paylaşımı en üst düzeye çıkarmak için, verilerin kopyalanmakta olduğu kadar çok sayıda temsili sağlamanız gerekir. Ancak, zaman veya bellek kısıtlamaları nedeniyle, her bir veri türünü çalışma alanına yazmak pratik olabilir.

Bu durumda, ilk veri gösterimini çalışma alanına yerleştirebilirsiniz ve alıcı uygulama farklı bir temsil isteyebilir ve bu, yapıştırma işleminden hemen önce bir arada oluşturulabilir.

Çalışma alanına ilk öğeyi yerleştirdiğinizde, kullanılabilir bir veya daha fazla temsilin arabirime uygun bir nesne tarafından sağlandığını belirtirsiniz NSPasteboardItemDataProvider . Bu nesneler, alıcı uygulama tarafından istenen şekilde isteğe bağlı olarak ek temsiller sağlar.

Değişiklik sayısı

Her çalışma alanı, yeni bir sahibin bildirildiği her seferinde artan değişiklik sayısını tutar. Bir uygulama, değişiklik sayısının değerini denetleyerek çalışma alanı içeriğinin, son incelenmeden bu yana değişip değişmediğini tespit edebilir.

ChangeCountClearContentsNSPasteboard Belirli bir çalışma alanının değişiklik sayısını değiştirmek için sınıfının ve yöntemlerini kullanın.

Çalışma alanına veri kopyalama

Çalışma alanına erişerek bir kopyalama işlemi gerçekleştirirsiniz, var olan tüm içerikleri temizleyerek ve verilerin çok sayıda gösterimi çalışma alanına gerekli olacak şekilde yazıyor.

Örnek:

// 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});

Genellikle, yukarıdaki örnekte yaptığımız gibi yalnızca genel çalışma alanına yazabileceksiniz. Yöntemine yollamak istediğiniz herhangi bir nesne WriteObjects arabirimine uygun WriteObjectsINSPasteboardWriting . Birkaç, yerleşik Sınıf (örneğin,,, NSString , NSImageNSURLNSColorNSAttributedString , ve NSPasteboardItem ) otomatik olarak bu arabirime uyar.

Çalışma alanına özel bir veri sınıfı yazıyorsanız, INSPasteboardWriting arabirime uyması veya sınıfın bir örneğine sarmalanması gerekir NSPasteboardItem (aşağıdaki INSPasteboardWriting bölümüne bakın).

Çalışma alanından veri okuma

Yukarıda belirtildiği gibi, uygulamalar arasında veri paylaşma potansiyelini en üst düzeye çıkarmak için kopyalanmış verilerin birden çok gösterimi çalışma alanına yazılabilir. BT, özellikleri için mümkün olan en zengin sürümü (varsa) seçmek için alıcı uygulamaya yöneliktir.

Basit yapıştırma işlemi

Yöntemini kullanarak çalışma alanındaki verileri okuyabilirsiniz ReadObjectsForClasses . İki parametre gerektirir:

  1. NSObjectÇalışma alanından okumak istediğiniz temel sınıf türleri dizisi. Bunu, en fazla istenen veri türüyle, daha sonra kalan herhangi bir şekilde azalan tercihle sipariş etmelisiniz.
  2. Ek kısıtlamalar (örneğin, belirli URL içerik türleriyle sınırlama) veya başka kısıtlamalar gerekmiyorsa boş bir sözlük içeren bir sözlük.

Yöntemi, geçirdiğimiz ölçütlere uyan öğelerin bir dizisini döndürür ve bu nedenle, istenen sayıda veri türünü içerir. istenen türlerin hiçbiri mevcut olmadığından boş bir dizi döndürülmek de mümkündür.

Örneğin, aşağıdaki kod, genel çalışma alanında olup olmadığını denetler ve bunu yapmak için bir NSImage görüntü kutusu içinde görüntüler.

[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];
            }
}

Birden çok veri türü isteme

Oluşturulan Xamarin. Mac uygulamasının türüne bağlı olarak, yapıştırılan verilerin birden fazla temsilini işleyebilir. Bu durumda, çalışma alanından veri almak için iki senaryo vardır:

  1. Yöntemine tek bir çağrı yapın ReadObjectsForClasses ve istediğiniz gösterimlerden (tercih edilen sırada) oluşan bir dizi sağlayın.
  2. ReadObjectsForClassesHer seferinde farklı türde bir diziyi soran yönteme birden çok çağrı yapın.

Bir çalışma alanından veri alma hakkında daha fazla ayrıntı için yukarıdaki basit yapıştırma işlemi bölümüne bakın.

Var olan veri türleri denetleniyor

Çalışma alanının, çalışma alanındaki verileri gerçekten okumadan, belirli bir veri gösterimi içerip içermediği durumlarda ( Yapıştırma menü öğesini yalnızca geçerli veriler varsa etkinleştirin) kontrol etmek isteyebilirsiniz.

CanReadObjectForClassesVerilen bir tür içerip içermediğinden görmek için çalışma alanının yöntemini çağırın.

Örneğin, aşağıdaki kod genel çalışma alanının bir örnek içerip içermeyeceğini belirler 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);
    }
}

Çalışma alanından URL 'leri okuma

Belirli bir Xamarin. Mac uygulamasının işlevine bağlı olarak, bir çalışma alanından URL 'Leri okumak gerekebilir, ancak yalnızca belirli bir ölçüt kümesini (örneğin, belirli bir veri türünün dosya veya URL 'Leri işaret eden) karşılıyorsa. Bu durumda, veya yöntemlerinin ikinci parametresini kullanarak ek arama ölçütleri belirtebilirsiniz CanReadObjectForClassesReadObjectsForClasses .

Özel veri türleri

Kendi özel türlerinizi bir Xamarin. Mac uygulamasının çalışma alanına kaydetmeniz gereken zamanlar vardır. Örneğin, kullanıcının çizim nesnelerini kopyalamasını ve yapıştırmasını sağlayan bir vektör çizim uygulaması.

Bu durumda, veri özel sınıfınızı, öğesinden devralanabilmesi NSObject ve birkaç arabirime ( INSCodingINSPasteboardWriting ve) uygun olacak şekilde tasarlamanız gerekir INSPasteboardReading . İsteğe bağlı olarak, NSPasteboardItem Kopyalanacak veya yapıştırılacak verileri kapsüllemek için bir kullanabilirsiniz.

Bu seçeneklerin her ikisi de aşağıda ayrıntılarıyla ele alınacaktır.

Özel bir sınıf kullanma

Bu bölümde, bu belgenin başlangıcında oluşturduğumuz basit örnek uygulamayı ve Windows arasında kopyaladığımız ve yapıştırmakta olduğumuz görüntüyle ilgili bilgileri izlemek için özel bir sınıf ekleyerek genişletireceğiz.

Projeye yeni bir sınıf ekleyin ve IMAGEINFO. cs' i çağırın. Dosyayı düzenleyin ve aşağıdaki gibi görünmesini sağlayın:

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
    }
}
    

Aşağıdaki bölümlerde bu sınıfa ayrıntılı bir bakış göndereceğiz.

Devralma ve arabirimler

Özel bir veri sınıfına bir çalışma alanına yazılamaz veya buradan okuma yapmadan önce, INSPastebaordWriting ve INSPasteboardReading arabirimleriyle uyumlu olmalıdır. Ayrıca, öğesinden devralması NSObject ve arabiriminden de uymalıdır INSCoding :

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

Sınıfı, yönergesi kullanılarak da gösterilmeli Objective-CRegister ve kullanarak gerekli özellikleri veya yöntemleri kullanıma sunmalıdır Export . Örnek:

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

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

Bu sınıfın içereceği iki veri alanını (görüntünün adı ve türü (jpg, PNG, vb.) kullanıma sunuyoruz.

Daha fazla bilgi için, Exposing C# classes / methods to Objective-CExposing C# classes / methods to Objective-C belgelerinin bölümüne bakın RegisterExport . C# sınıflarınızı Objective-C nesneler ve Kullanıcı Arabirimi öğelerine bağlamak için kullanılan ve özniteliklerini açıklar.

Oluşturucular

Objective-CÇalışma alanından okunabilmesi için, özel veri sınıfımız için iki Oluşturucu (doğru şekilde kullanıma sunulacaktır) gerekecektir:

[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 ();
}

İlk olarak, varsayılan yöntemi olan boş oluşturucuyu kullanıma sunduk init .

Daha sonra, ' ın ' ın NSCoding altına yapıştırırken çalışma alanından nesnenin yeni bir örneğini oluşturmak için kullanılacak uyumlu bir Oluşturucu sunuyoruz initWithCoder .

Bu Oluşturucu bir NSCoder ( NSKeyedArchiver çalışma alanına yazıldığında bir tarafından oluşturulan), anahtar/değer eşleştirilmiş verileri ayıklar ve veri sınıfının özellik alanlarına kaydeder.

Çalışma alanına yazma

Arabirime uygun olarak, INSPasteboardWriting sınıfın çalışma alanına yazılabilmesi için iki yöntemi ve isteğe bağlı olarak üçüncü bir yöntemi göstermemiz gerekir.

İlk olarak, çalışma alanına özel sınıfın hangi veri türü temsillerine yazılabileceğini söyliyoruz:

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

Her gösterim, sunulan verilerin türünü benzersiz bir şekilde tanımlayan bir basit dizeden daha fazla olmayan bir Tekdüzen tür tanımlayıcısı (UTI) aracılığıyla tanımlanır (daha fazla bilgi için bkz. Apple 'ın Tekdüzen tür tanımlayıcılarına genel bakış belgeleri).

Özel biçimimiz için kendi UTı: "com. Xamarin. Image-info" (bir uygulama tanımlayıcısı gibi ters gösterimde) oluşturuluyor. Sınıfımız Ayrıca, çalışma alanına () standart bir dize yazabileceğinden public.text .

Sonra, nesneyi istenen biçimde, çalışma alanına yazılacak şekilde oluşturuyoruz:

[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;
}

Türü için public.text basit, biçimlendirilen bir nesne döndürüyoruz NSString . Özel tür için com.xamarin.image-info , NSKeyedArchiverNSCoder özel veri sınıfını bir anahtar/değer eşleştirilmiş arşive kodlamak üzere bir ve arabirimi kullanıyoruz. Kodlamayı gerçekten işlemek için aşağıdaki yöntemi uygulamamız gerekir:

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

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

Bağımsız anahtar/değer çiftleri kodlayıcıya yazılır ve yukarıda eklediğimiz ikinci Oluşturucu kullanılarak kodu çözülür.

İsteğe bağlı olarak, çalışma alanına veri yazarken herhangi bir seçeneği tanımlamak için aşağıdaki yöntemi dahil edebilirsiniz:

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

Şu anda yalnızca WritingPromised seçenek kullanılabilir ve belirli bir tür yalnızca taahhüt edildiğinde ve yalnızca çalışma alanına yazılmadığından kullanılmalıdır. Daha fazla bilgi için lütfen yukarıdaki taahhüt edilen veriler bölümüne bakın.

Bu yöntemler yerine, çalışma alanına özel sınıfınızı yazmak için aşağıdaki kod kullanılabilir:

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

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

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

Çalışma alanından okuma

INSPasteboardReadingArabirimine uygun olarak, özel veri sınıfının çalışma alanından okuyabilmesi için üç yöntemi kullanıma sunduk.

İlk olarak, çalışma alanına özel sınıfın panodan okuyabilecekleri veri türü temsillerini söylememiz gerekir:

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

Bunlar, basit kullanım olarak tanımlanır ve yukarıdaki çalışma alanına yazma bölümünde tanımladığımız türlerdir.

Ardından, aşağıdaki yöntemi kullanarak UTI türlerinin her birinin nasıl okunacaklarını bir çalışma alanına söylüyoruz:

[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;
}

Tür için, com.xamarin.image-info çalışma alanına, sınıfa NSKeyedArchiver eklediğimiz oluşturucuyu çağırarak çalışma alanına sınıfı yazarken oluşturduğumuz anahtar/değer çiftinin kodunu çözmeye söyliyoruz initWithCoder: .

Son olarak, çalışma alanından diğer UTI veri gösterimlerini okumak için aşağıdaki yöntemi eklememiz gerekir:

[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;
}

Tüm bu yöntemler söz konusu olduğunda, özel veri sınıfı aşağıdaki kod kullanılarak çalışma alanından okunabilir:

// 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];
}

Nspasteboardıtem kullanma

Özel bir sınıfın oluşturulmasını garanti etmez veya yalnızca gerekli olduğu gibi ortak bir biçimde veri sağlamak istediğinizde, çalışma alanına özel öğeler yazmanız gerektiği zamanlar olabilir. Bu durumlar için bir kullanabilirsiniz NSPasteboardItem .

NSPasteboardItem, Çalışma alanına yazılan veriler üzerinde ayrıntılı denetim sağlar ve geçici erişim için tasarlandıktan sonra, çalışma alanına yazıldıktan sonra atılmalıdır.

Veri yazma

Özel verilerinizi bir öğesine yazmak için NSPasteboardItem özel bir sağlamanız gerekir NSPasteboardItemDataProvider . Projeye yeni bir sınıf ekleyin ve ımageınfodataprovider. cs' i çağırın. Dosyayı düzenleyin ve aşağıdaki gibi görünmesini sağlayın:

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
    }
}

Özel veri sınıfı ile yaptığımız gibi, ve ' yi olarak göstermek için Register ve Export yönergelerini kullanmanız gerekir Objective-C . Sınıf öğesinden devralması NSPasteboardItemDataProvider ve FinishedWithDataProvider ve yöntemlerinin uygulanması gerekir ProvideDataForType .

ProvideDataForTypeAşağıdaki şekilde Sarmalanacak verileri sağlamak için yöntemini kullanın 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;
    }

}

Bu durumda, görüntümiz (Name ve ImageType) hakkındaki iki bilgi parçasını saklarız ve bunları basit bir dizeye () yazıyoruz public.text .

Çalışma alanına verileri yaz yazın, aşağıdaki kodu kullanın:

// 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 });
}

Verileri okuma

Çalışma alanından geri veri okumak için aşağıdaki kodu kullanın:

// 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
    ...
}

Özet

Bu makale, kopyalama ve yapıştırma işlemlerini desteklemek için bir Xamarin. Mac uygulamasındaki çalışma alanıyla çalışmaya ilişkin ayrıntılı bir bakış gerçekleştirmiştir. İlk olarak, standart pasteboards işlemleri hakkında bilgi sahibi olmak için basit bir örnek getirmiştir. Sonra, çalışma alanına ayrıntılı bir bakış ve verileri okuma ve yazma hakkında ayrıntılı bir bakış gerçekleşecektir. Son olarak, bir uygulama içinde karmaşık veri türlerini kopyalamayı ve yapıştırmayı desteklemek için özel bir veri türü kullanmaya bakıyordu.