Bagikan melalui


Salin dan tempel di Xamarin.Mac

Artikel ini membahas bekerja dengan papan tempel untuk menyediakan salin dan tempel di aplikasi Xamarin.Mac. Ini menunjukkan cara bekerja dengan jenis data standar yang dapat dibagikan antara beberapa aplikasi dan cara mendukung data kustom dalam aplikasi tertentu.

Gambaran Umum

Saat bekerja dengan C# dan .NET dalam aplikasi Xamarin.Mac, Anda memiliki akses ke dukungan pasteboard (salin dan tempel) yang sama dengan yang dimiliki pengembang yang bekerja Objective-C .

Dalam artikel ini kita akan membahas dua cara utama untuk menggunakan pasteboard di aplikasi Xamarin.Mac:

  1. Jenis Data Standar - Karena operasi pasteboard biasanya dilakukan di antara dua aplikasi yang tidak terkait, tidak ada aplikasi yang mengetahui jenis data yang didukung oleh yang lain. Untuk memaksimalkan potensi berbagi, papan tempel dapat menyimpan beberapa representasi item tertentu (menggunakan sekumpulan standar jenis data umum), ini memungkinkan aplikasi yang menggunakan untuk memilih versi yang paling cocok untuk kebutuhannya.
  2. Data Kustom - Untuk mendukung penyalinan dan penempelan data kompleks dalam Xamarin.Mac Anda, Anda dapat menentukan jenis data kustom yang akan ditangani oleh pasteboard. Misalnya, aplikasi gambar vektor yang memungkinkan pengguna menyalin dan menempelkan bentuk kompleks yang terdiri dari beberapa jenis dan titik data.

Contoh aplikasi yang sedang berjalan

Dalam artikel ini, kita akan membahas dasar-dasar bekerja dengan pasteboard dalam aplikasi Xamarin.Mac untuk mendukung operasi salin dan tempel. Sangat disarankan agar Anda bekerja melalui artikel Hello, Mac terlebih dahulu, khususnya bagian Pengenalan Xcode dan Penyusun Antarmuka dan Outlet dan Tindakan , karena mencakup konsep dan teknik utama yang akan kita gunakan dalam artikel ini.

Anda mungkin ingin melihat kelas /metode Exposing C# ke Objective-Cbagian dari dokumen Xamarin.Mac Internals juga, ini menjelaskan Register atribut dan Export yang digunakan untuk menghubungkan kelas C# Anda ke Objective-C objek dan elemen UI.

Mulai menggunakan papan tempel

Papan tempel menyajikan mekanisme standar untuk bertukar data dalam aplikasi tertentu atau antar aplikasi. Penggunaan umum untuk pasteboard dalam aplikasi Xamarin.Mac adalah untuk menangani operasi salin dan tempel, namun sejumlah operasi lain juga didukung (seperti Drag & Drop dan Application Services).

Untuk membuat Anda keluar dari tanah dengan cepat, kita akan mulai dengan pengantar sederhana dan praktis untuk menggunakan papan tempel di aplikasi Xamarin.Mac. Nantinya, kami akan memberikan penjelasan mendalam tentang cara kerja papan tempel dan metode yang digunakan.

Untuk contoh ini, kita akan membuat aplikasi berbasis dokumen sederhana yang mengelola jendela yang berisi tampilan gambar. Pengguna akan dapat menyalin dan menempelkan gambar antara dokumen di aplikasi dan ke atau dari aplikasi lain atau beberapa jendela di dalam aplikasi yang sama.

Membuat proyek Xamarin

Pertama, kita akan membuat aplikasi Xamarin.Mac berbasis dokumen baru yang akan kita tambahkan dukungan salin dan tempel.

Lakukan:

  1. Mulai Visual Studio untuk Mac dan klik tautan Proyek Baru... .

  2. Pilih App Mac>>Cocoa App, lalu klik tombol Berikutnya:

    Membuat proyek aplikasi Kakao baru

  3. Masukkan MacCopyPaste untuk Nama Proyek dan pertahankan yang lain sebagai default. Klik Berikutnya:

    Mengatur nama proyek

  4. Klik tombol Buat :

    Mengonfirmasi pengaturan proyek baru

Menambahkan NSDocument

Selanjutnya kita akan menambahkan kelas kustom NSDocument yang akan bertindak sebagai penyimpanan latar belakang untuk antarmuka pengguna aplikasi. Ini akan berisi satu Tampilan Gambar dan tahu cara menyalin gambar dari tampilan ke papan tempel default dan cara mengambil gambar dari papan tempel default dan menampilkannya di Tampilan Gambar.

Klik kanan pada proyek Xamarin.Mac di Solution Pad dan pilih Tambahkan>File Baru..:

Menambahkan NSDocument ke proyek

Masukkan ImageDocument untuk Nama dan klik tombol Baru . Edit kelas ImageDocument.cs dan buat terlihat seperti berikut ini:

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

Mari kita lihat beberapa kode secara rinci di bawah ini.

Kode berikut menyediakan properti untuk menguji keberadaan data gambar pada pasteboard default, jika gambar tersedia, true dikembalikan lagi 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);
    }
}

Kode berikut menyalin gambar dari tampilan gambar terlampir ke dalam papan tempel default:

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

}

Dan kode berikut menempelkan gambar dari papan tempel default dan menampilkannya dalam tampilan gambar terlampir (jika papan tempel berisi gambar yang valid):

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

Dengan dokumen ini di tempat, kita akan membuat antarmuka pengguna untuk aplikasi Xamarin.Mac.

Membangun antarmuka pengguna

Klik dua kali file Main.storyboard untuk membukanya di Xcode. Selanjutnya, tambahkan toolbar dan gambar dengan baik dan konfigurasikan sebagai berikut:

Mengedit toolbar

Tambahkan salin dan tempel Item Bilah Alat Gambar di sisi kiri toolbar. Kami akan menggunakannya sebagai pintasan untuk menyalin dan menempelkan dari menu Edit. Selanjutnya, tambahkan empat Item Toolbar Gambar ke sisi kanan toolbar. Kami akan menggunakannya untuk mengisi gambar dengan baik dengan beberapa gambar default.

Untuk informasi selengkapnya tentang bekerja dengan toolbar, silakan lihat dokumentasi Toolbar kami.

Selanjutnya, mari kita ekspos outlet dan tindakan berikut untuk item toolbar kami dan gambar dengan baik:

Membuat outlet dan tindakan

Untuk informasi selengkapnya tentang bekerja dengan outlet dan tindakan, silakan lihat bagian Outlet dan Tindakan dari dokumentasi Hello, Mac kami.

Mengaktifkan antarmuka pengguna

Dengan antarmuka pengguna kami yang dibuat di Xcode dan elemen UI kami yang diekspos melalui outlet dan tindakan, kita perlu menambahkan kode untuk mengaktifkan UI. Klik dua kali file ImageWindow.cs di Solution Pad dan buatlah terlihat seperti berikut ini:

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

Mari kita lihat kode ini secara rinci di bawah ini.

Pertama, kami mengekspos instans ImageDocument kelas yang kami buat di atas:

private ImageDocument _document;
...

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

Dengan menggunakan Export, WillChangeValue dan DidChangeValue, kami telah menyiapkan Document properti untuk memungkinkan Pengodean Kunci-Nilai dan Pengikatan Data di Xcode.

Kami juga mengekspos Gambar dari sumur gambar yang kami tambahkan ke UI kami di Xcode dengan properti berikut:

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

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

Ketika Jendela Utama dimuat dan ditampilkan, kami membuat instans kelas kami ImageDocument dan melampirkan gambar UI dengan baik ke dalamnya dengan kode berikut:

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

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

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

Terakhir, sebagai respons terhadap pengguna yang mengklik item toolbar salin dan tempel, kami memanggil instans ImageDocument kelas untuk melakukan pekerjaan aktual:

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

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

Mengaktifkan menu File dan Edit

Hal terakhir yang perlu kita lakukan adalah mengaktifkan item menu Baru dari menu File (untuk membuat instans baru dari jendela utama kita) dan untuk mengaktifkan item menu Potong, Salin, dan Tempel dari menu Edit.

Untuk mengaktifkan item menu Baru , edit file AppDelegate.cs dan tambahkan kode berikut:

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

Untuk informasi selengkapnya, silakan lihat bagian Bekerja dengan Beberapa Windows dari dokumentasi Windows kami.

Untuk mengaktifkan item menu Potong, Salin, dan Tempel, edit file AppDelegate.cs dan tambahkan kode berikut:

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

Untuk setiap item menu, kita mendapatkan jendela kunci saat ini, paling atas, dan melemparkannya ke kelas kita ImageWindow :

var window = NSApplication.SharedApplication.KeyWindow as ImageWindow;

Dari sana kita memanggil ImageDocument instans kelas jendela tersebut untuk menangani tindakan salin dan tempel. Contohnya:

window.Document.CopyImage (sender);

Kami hanya ingin item menu Potong, Salin, dan Tempel dapat diakses jika ada data gambar di papan tempel default atau di sumur gambar jendela aktif saat ini.

Mari kita tambahkan file EditMenuDelegate.cs ke proyek Xamarin.Mac dan membuatnya terlihat seperti berikut:

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

Sekali lagi, kita mendapatkan jendela paling atas saat ini dan menggunakan instans kelasnya ImageDocument untuk melihat apakah data gambar yang diperlukan ada. Kemudian kita menggunakan MenuWillHighlightItem metode untuk mengaktifkan atau menonaktifkan setiap item berdasarkan status ini.

Edit file AppDelegate.cs dan buat DidFinishLaunching metode terlihat seperti berikut ini:

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

Pertama, kami menonaktifkan pengaktifan dan penonaktifan item menu secara otomatis di menu Edit. Selanjutnya, kami melampirkan EditMenuDelegate instans kelas yang kami buat di atas.

Untuk informasi selengkapnya, silakan lihat dokumentasi Menu kami.

Menguji aplikasi

Dengan segala sesuatu di tempat, kami siap untuk menguji aplikasi. Bangun dan jalankan aplikasi dan antarmuka utama ditampilkan:

Menjalankan aplikasi

Jika Anda membuka menu Edit, perhatikan bahwa Potong, Salin, dan Tempel dinonaktifkan karena tidak ada gambar di gambar dengan baik atau di papan tempel default:

Membuka menu Edit

Jika Anda menambahkan gambar ke gambar dengan baik dan membuka kembali menu Edit, item sekarang akan diaktifkan:

Memperlihatkan item menu Edit diaktifkan

Jika Anda menyalin gambar dan memilih Baru dari menu file, Anda dapat menempelkan gambar tersebut ke jendela baru:

Menempelkan gambar ke jendela baru

Di bagian berikut, kita akan melihat secara rinci bekerja dengan pasteboard di aplikasi Xamarin.Mac.

Tentang papan tempel

Di macOS (sebelumnya dikenal sebagai OS X) papan tempel (NSPasteboard) menyediakan dukungan untuk beberapa proses server seperti Salin & Tempel, Seret & Letakkan dan Layanan Aplikasi. Di bagian berikut, kita akan melihat lebih dekat beberapa konsep papan tempel kunci.

Apa itu papan tempel?

Kelas ini NSPasteboard menyediakan mekanisme standar untuk bertukar informasi antara aplikasi atau dalam aplikasi tertentu. Fungsi utama pasteboard adalah untuk menangani operasi salin dan tempel:

  1. Saat pengguna memilih item di aplikasi dan menggunakan item menu Potong atau Salin , satu atau beberapa representasi item yang dipilih ditempatkan di papan tempel.
  2. Saat pengguna menggunakan item menu Tempel (dalam aplikasi yang sama atau yang berbeda), versi data yang dapat ditanganinya disalin dari pasteboard dan ditambahkan ke aplikasi.

Penggunaan papan tempel yang kurang jelas termasuk operasi temukan, seret, seret dan letakkan, dan layanan aplikasi:

  • Saat pengguna memulai operasi seret, data seret disalin ke papan tempel. Jika operasi seret berakhir dengan penurunan ke aplikasi lain, aplikasi tersebut menyalin data dari papan tempel.
  • Untuk layanan terjemahan, data yang akan diterjemahkan disalin ke pasteboard oleh aplikasi yang meminta. Layanan aplikasi, mengambil data dari pasteboard, melakukan terjemahan, lalu menempelkan data kembali di papan tempel.

Dalam bentuk paling sederhana, pasteboard digunakan untuk memindahkan data di dalam aplikasi tertentu atau di antara aplikasi dan ada di area memori global khusus di luar proses aplikasi. Meskipun konsep papan tempel mudah dipahami, ada beberapa detail yang lebih kompleks yang harus dipertimbangkan. Ini akan dibahas secara rinci di bawah ini.

Papan tempel bernama

Papan tempel dapat bersifat publik atau privat dan dapat digunakan untuk berbagai tujuan dalam aplikasi atau di antara beberapa aplikasi. macOS menyediakan beberapa pasteboard standar, masing-masing dengan penggunaan tertentu yang terdefinisi dengan baik:

  • NSGeneralPboard- Pasteboard default untuk operasi Potong, Salin, dan Tempel.
  • NSRulerPboard- Mendukung operasi Potong, Salin, dan Tempel pada Penggaris.
  • NSFontPboard- Mendukung operasi Potong, Salin, dan Tempel pada NSFont objek.
  • NSFindPboard - Mendukung panel temuan khusus aplikasi yang dapat berbagi teks pencarian.
  • NSDragPboard - Mendukung operasi Seret & Lepas .

Untuk sebagian besar situasi, Anda akan menggunakan salah satu papan tempel yang ditentukan sistem. Tetapi mungkin ada situasi yang mengharuskan Anda membuat papan tempel Anda sendiri. Dalam situasi ini, Anda dapat menggunakan FromName (string name) metode NSPasteboard kelas untuk membuat papan tempel kustom dengan nama yang diberikan.

Secara opsional, Anda dapat memanggil CreateWithUniqueName metode NSPasteboard kelas untuk membuat papan tempel bernama unik.

Item papan tempel

Setiap bagian data yang ditulis aplikasi ke papan tempel dianggap sebagai Item Papan Tempel dan papan tempel dapat menyimpan beberapa item secara bersamaan. Dengan cara ini, aplikasi dapat menulis beberapa versi data yang disalin ke papan tempel (misalnya, teks biasa dan teks yang diformat) dan aplikasi pengambilan hanya dapat membaca data yang dapat diproses (seperti teks biasa saja).

Representasi data dan pengidentifikasi jenis seragam

Operasi pasteboard biasanya berlangsung antara dua aplikasi (atau lebih) yang tidak memiliki pengetahuan satu sama lain atau jenis data yang dapat ditangani masing-masing. Seperti yang dinyatakan dalam bagian di atas, untuk memaksimalkan potensi berbagi informasi, papan tempel dapat menyimpan beberapa representasi data yang disalin dan ditempelkan.

Setiap representasi diidentifikasi melalui Pengidentifikasi Jenis Seragam (UTI), yang tidak lebih dari string sederhana yang secara unik mengidentifikasi jenis tanggal yang disajikan (untuk informasi selengkapnya, silakan lihat dokumentasi Gambaran Umum Pengidentifikasi Jenis Seragam Apple).

Jika Anda membuat jenis data kustom (misalnya, objek gambar di aplikasi gambar vektor), Anda dapat membuat UTI Anda sendiri untuk mengidentifikasinya secara unik dalam operasi salin dan tempel.

Saat aplikasi bersiap untuk menempelkan data yang disalin dari papan tempel, aplikasi harus menemukan representasi yang paling sesuai dengan kemampuannya (jika ada). Biasanya ini akan menjadi jenis terkaya yang tersedia (misalnya teks yang diformat untuk aplikasi pemrosesan kata), kembali ke formulir paling sederhana yang tersedia sesuai kebutuhan (teks biasa untuk editor teks sederhana).

Data yang dijanjikan

Secara umum, Anda harus memberikan sebanyak mungkin representasi data yang disalin untuk memaksimalkan berbagi antar aplikasi. Namun, karena kendala waktu atau memori, mungkin tidak praktis untuk benar-benar menulis setiap jenis data ke dalam papan tempel.

Dalam situasi ini, Anda dapat menempatkan representasi data pertama di papan tempel dan aplikasi penerima dapat meminta representasi yang berbeda, yang dapat dihasilkan secara on-the-fly tepat sebelum operasi tempel.

Saat Anda menempatkan item awal di papan tempel, Anda akan menentukan bahwa satu atau beberapa representasi lain yang tersedia disediakan oleh objek yang sesuai NSPasteboardItemDataProvider dengan antarmuka. Objek-objek ini akan memberikan representasi tambahan sesuai permintaan, seperti yang diminta oleh aplikasi penerima.

Ubah jumlah

Setiap papan tempel mempertahankan Jumlah Perubahan yang bertambah setiap kali pemilik baru dideklarasikan. Aplikasi dapat menentukan apakah konten papan tempel telah berubah sejak terakhir kali memeriksanya dengan memeriksa nilai Jumlah Perubahan.

ChangeCount Gunakan metode NSPasteboard dan ClearContents kelas untuk memodifikasi Jumlah Perubahan papan tempel tertentu.

Menyalin data ke papan tempel

Anda melakukan operasi salin dengan terlebih dahulu mengakses pasteboard, menghapus konten yang ada dan menulis representasi data sebanyak yang diperlukan ke pasteboard.

Contohnya:

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

Biasanya, Anda hanya akan menulis ke papan tempel umum, seperti yang telah kami lakukan dalam contoh di atas. Objek apa pun yang Anda kirim ke WriteObjects metode harus sesuai dengan INSPasteboardWriting antarmuka. Beberapa kelas bawaan (seperti NSString, , NSImage, NSURLNSColor, NSAttributedString, dan NSPasteboardItem) secara otomatis sesuai dengan antarmuka ini.

Jika Anda menulis kelas data kustom ke papan tempel, kelas tersebut harus sesuai dengan INSPasteboardWriting antarmuka atau dibungkus dalam instans NSPasteboardItem kelas (lihat bagian Jenis Data Kustom di bawah).

Membaca data dari papan tempel

Seperti yang dinyatakan di atas, untuk memaksimalkan potensi berbagi data antar aplikasi, beberapa representasi data yang disalin dapat ditulis ke pasteboard. Terserah aplikasi penerima untuk memilih versi terkaya yang mungkin untuk kemampuannya (jika ada).

Operasi tempel sederhana

Anda membaca data dari papan tempel menggunakan ReadObjectsForClasses metode . Ini akan memerlukan dua parameter:

  1. Array jenis NSObject kelas berbasis yang ingin Anda baca dari papan tempel. Anda harus memesan ini dengan jenis data yang paling diinginkan terlebih dahulu, dengan jenis yang tersisa dalam preferensi yang menurun.
  2. Kamus yang berisi batasan tambahan (seperti membatasi jenis konten URL tertentu) atau kamus kosong jika tidak ada batasan lebih lanjut yang diperlukan.

Metode mengembalikan array item yang memenuhi kriteria yang kami lewati dan oleh karena itu berisi paling banyak jumlah jenis data yang sama yang diminta. ada juga kemungkinan bahwa tidak ada jenis yang diminta dan array kosong akan dikembalikan.

Misalnya, kode berikut memeriksa untuk melihat apakah NSImage ada di papan tempel umum dan menampilkannya dalam gambar dengan baik jika ada:

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

Meminta beberapa jenis data

Berdasarkan jenis aplikasi Xamarin.Mac yang sedang dibuat, aplikasi mungkin dapat menangani beberapa representasi data yang ditempelkan. Dalam situasi ini, ada dua skenario untuk mengambil data dari papan tempel:

  1. Lakukan satu panggilan ke ReadObjectsForClasses metode dan berikan array dari semua representasi yang Anda inginkan (dalam urutan yang disukai).
  2. Lakukan beberapa panggilan ke ReadObjectsForClasses metode yang meminta array jenis yang berbeda setiap kali.

Lihat bagian Operasi Tempel Sederhana di atas untuk detail selengkapnya tentang mengambil data dari papan tempel.

Memeriksa jenis data yang sudah ada

Ada kalanya Anda mungkin ingin memeriksa apakah papan tempel berisi representasi data tertentu tanpa benar-benar membaca data dari papan tempel (seperti mengaktifkan item menu Tempel hanya ketika data yang valid ada).

CanReadObjectForClasses Panggil metode papan tempel untuk melihat apakah berisi jenis tertentu.

Misalnya, kode berikut menentukan apakah pasteboard umum berisi NSImage instans:

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

Membaca url dari pasteboard

Berdasarkan fungsi aplikasi Xamarin.Mac tertentu, mungkin diperlukan untuk membaca URL dari pasteboard, tetapi hanya jika memenuhi serangkaian kriteria tertentu (seperti menunjuk ke file atau URL dari jenis data tertentu). Dalam situasi ini, Anda dapat menentukan kriteria pencarian tambahan menggunakan parameter kedua dari CanReadObjectForClasses metode atau ReadObjectsForClasses .

Jenis data kustom

Ada kalanya Anda perlu menyimpan jenis kustom Anda sendiri ke papan tempel dari aplikasi Xamarin.Mac. Misalnya, aplikasi gambar vektor yang memungkinkan pengguna menyalin dan menempelkan objek gambar.

Dalam situasi ini, Anda harus merancang kelas kustom data Anda sehingga mewarisi dan NSObject sesuai dengan beberapa antarmuka (INSCoding, INSPasteboardWriting dan INSPasteboardReading). Secara opsional, Anda dapat menggunakan NSPasteboardItem untuk merangkum data yang akan disalin atau ditempelkan.

Kedua opsi ini akan dibahas secara rinci di bawah ini.

Menggunakan kelas kustom

Di bagian ini kita akan memperluas aplikasi contoh sederhana yang kita buat di awal dokumen ini dan menambahkan kelas kustom untuk melacak informasi tentang gambar yang kita salin dan tempel di antara jendela.

Tambahkan kelas baru ke proyek dan sebut saja ImageInfo.cs. Edit file dan buat terlihat seperti berikut ini:

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

Di bagian berikut, kita akan melihat kelas ini secara terperinci.

Pewarisan dan antarmuka

Sebelum kelas data kustom dapat ditulis atau dibaca dari papan tempel, kelas tersebut harus sesuai dengan INSPastebaordWriting antarmuka dan INSPasteboardReading . Selain itu, ia harus mewarisi dari NSObject dan juga sesuai dengan INSCoding antarmuka:

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

Kelas juga harus diekspos untuk Objective-C menggunakan direktif Register dan harus mengekspos properti atau metode yang diperlukan menggunakan Export. Contohnya:

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

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

Kami mengekspos dua bidang data yang akan dimuat kelas ini - nama gambar dan jenisnya (jpg, png, dll.).

Untuk informasi selengkapnya, lihat bagian Mengekspos kelas /metode C# ke Objective-Cbagian dokumentasi Xamarin.Mac Internals, ini menjelaskan Register atribut dan Export yang digunakan untuk menghubungkan kelas C# Anda ke Objective-C objek dan elemen UI.

Konstruktor

Dua konstruktor (diekspos dengan benar ke Objective-C) akan diperlukan untuk kelas data kustom kami sehingga dapat dibaca dari papan tempel:

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

Pertama, kami mengekspos konstruktor kosong di bawah metode initdefault Objective-C .

Selanjutnya, kami mengekspos NSCoding konstruktor yang sesuai yang akan digunakan untuk membuat instans baru objek dari pasteboard saat menempelkan dengan nama yang diekspor .initWithCoder

Konstruktor ini mengambil (seperti yang NSCoder NSKeyedArchiver dibuat oleh ketika ditulis ke pasteboard), mengekstrak data berpasangan kunci/nilai dan menyimpannya ke bidang properti kelas data.

Menulis ke papan tempel

Dengan menyesuaikan dengan INSPasteboardWriting antarmuka, kita perlu mengekspos dua metode, dan secara opsional metode ketiga, sehingga kelas dapat ditulis ke pasteboard.

Pertama, kita perlu memberi tahu pasteboard representasi jenis data apa yang dapat ditulis oleh kelas kustom:

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

Setiap representasi diidentifikasi melalui Pengidentifikasi Jenis Seragam (UTI), yang tidak lebih dari string sederhana yang secara unik mengidentifikasi jenis data yang disajikan (untuk informasi selengkapnya, silakan lihat dokumentasi Gambaran Umum Pengidentifikasi Jenis Seragam Apple).

Untuk format kustom kami, kami membuat UTI kami sendiri: "com.xamarin.image-info" (perhatikan bahwa dalam notasi terbalik sama seperti Pengidentifikasi Aplikasi). Kelas kami juga mampu menulis string standar ke pasteboard (public.text).

Selanjutnya, kita perlu membuat objek dalam format yang diminta yang benar-benar ditulis ke pasteboard:

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

Untuk jenisnya public.text , kita mengembalikan objek sederhana yang diformat NSString . Untuk jenis kustom com.xamarin.image-info , kami menggunakan antarmuka NSKeyedArchiver dan NSCoder untuk mengodekan kelas data kustom ke arsip berpasangan kunci/nilai. Kita perlu menerapkan metode berikut untuk benar-benar menangani pengodean:

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

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

Pasangan kunci/nilai individual ditulis ke encoder dan akan didekodekan menggunakan konstruktor kedua yang kami tambahkan di atas.

Secara opsional, kita dapat menyertakan metode berikut untuk menentukan opsi apa pun saat menulis data ke pasteboard:

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

Saat ini hanya opsi yang WritingPromised tersedia dan harus digunakan ketika jenis tertentu hanya dijanjikan dan tidak benar-benar ditulis ke pasteboard. Untuk informasi selengkapnya, silakan lihat bagian Data yang Dijanjikan di atas.

Dengan metode ini di tempat, kode berikut dapat digunakan untuk menulis kelas kustom kami ke pasteboard:

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

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

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

Membaca dari papan tempel

Dengan sesuai dengan INSPasteboardReading antarmuka, kita perlu mengekspos tiga metode sehingga kelas data kustom dapat dibaca dari pasteboard.

Pertama, kita perlu memberi tahu papan tempel representasi jenis data apa yang dapat dibaca kelas kustom dari clipboard:

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

Sekali lagi, ini didefinisikan sebagai UTI sederhana dan merupakan jenis yang sama yang kami tentukan dalam bagian Menulis ke Papan Tempel di atas.

Selanjutnya, kita perlu memberi tahu papan tempel bagaimana masing-masing jenis UTI akan dibaca menggunakan metode berikut:

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

Untuk jenisnya com.xamarin.image-info , kami memberi tahu papan tempel untuk mendekode pasangan kunci/nilai yang kami buat dengan NSKeyedArchiver saat menulis kelas ke papan tempel dengan memanggil initWithCoder: konstruktor yang kami tambahkan ke kelas .

Terakhir, kita perlu menambahkan metode berikut untuk membaca representasi data UTI lainnya dari pasteboard:

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

Dengan semua metode ini di tempat, kelas data kustom dapat dibaca dari papan tempel menggunakan kode berikut:

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

Menggunakan NSPasteboardItem

Mungkin ada kalanya Anda perlu menulis item kustom ke papan tempel yang tidak menjamin pembuatan kelas kustom atau Anda ingin memberikan data dalam format umum, hanya jika diperlukan. Untuk situasi ini, Anda dapat menggunakan NSPasteboardItem.

Memberikan NSPasteboardItem kontrol terperincah atas data yang ditulis ke papan tempel dan dirancang untuk akses sementara - harus dibuang setelah ditulis ke papan tempel.

Data tulis

Untuk menulis data kustom Anda ke, NSPasteboardItem Anda harus menyediakan kustom NSPasteboardItemDataProvider. Tambahkan kelas baru ke proyek dan sebut saja ImageInfoDataProvider.cs. Edit file dan buat terlihat seperti berikut ini:

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

Seperti yang kami lakukan dengan kelas data kustom, kita perlu menggunakan arahan Register dan Export untuk mengeksposnya ke Objective-C. Kelas harus mewarisi dari NSPasteboardItemDataProvider dan harus menerapkan FinishedWithDataProvider metode dan ProvideDataForType .

ProvideDataForType Gunakan metode untuk memberikan data yang akan dibungkus dalam NSPasteboardItem sebagai berikut:

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

}

Dalam hal ini, kami menyimpan dua informasi tentang gambar kami (Nama dan ImageType) dan menulisnya ke string sederhana (public.text).

Ketik tulis data ke pasteboard, gunakan kode berikut:

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

Membaca data

Untuk membaca kembali data dari pasteboard, gunakan kode berikut:

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

Ringkasan

Artikel ini telah melihat secara rinci tentang bekerja dengan papan tempel di aplikasi Xamarin.Mac untuk mendukung operasi salin dan tempel. Pertama, ini memperkenalkan contoh sederhana untuk membuat Anda terbiasa dengan operasi papan tempel standar. Selanjutnya, dibutuhkan tampilan terperinci pada papan tempel dan cara membaca dan menulis data darinya. Akhirnya, ia melihat menggunakan jenis data kustom untuk mendukung penyalinan dan penempelan jenis data kompleks dalam aplikasi.