Bagikan melalui


Tampilan Tabel di Xamarin.Mac

Artikel ini membahas cara bekerja dengan tampilan tabel dalam aplikasi Xamarin.Mac. Ini menjelaskan pembuatan tampilan tabel di Xcode dan Interface Builder dan berinteraksi dengannya dalam kode.

Saat bekerja dengan C# dan .NET dalam aplikasi Xamarin.Mac, Anda memiliki akses ke Tampilan Tabel yang sama dengan yang digunakan Objective-C pengembang dan Xcode . Karena Xamarin.Mac terintegrasi langsung dengan Xcode, Anda dapat menggunakan Penyusun Antarmuka Xcode untuk membuat dan memelihara Tampilan Tabel Anda (atau secara opsional membuatnya langsung dalam kode C#).

Tampilan Tabel menampilkan data dalam format tabular yang berisi satu atau beberapa kolom informasi dalam beberapa baris. Berdasarkan jenis Tampilan Tabel yang sedang dibuat, pengguna dapat mengurutkan menurut kolom, mengatur ulang kolom, menambahkan kolom, menghapus kolom, atau mengedit data yang terdapat dalam tabel.

Contoh tabel

Dalam artikel ini, kita akan membahas dasar-dasar bekerja dengan Tampilan Tabel dalam aplikasi Xamarin.Mac. 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# keObjective-Cbagian dari dokumen Xamarin.Mac Internals juga, ini menjelaskan Register perintah dan Export yang digunakan untuk menyambungkan kelas C# Anda ke Objective-C objek dan Elemen UI.

Pengantar Tampilan Tabel

Tampilan Tabel menampilkan data dalam format tabular yang berisi satu atau beberapa kolom informasi dalam beberapa baris. Tampilan Tabel ditampilkan di dalam Tampilan Gulir (NSScrollView) dan dimulai dengan macOS 10.7, Anda dapat menggunakan salah satu NSView alih-alih Sel (NSCell) untuk menampilkan baris dan kolom. Meskipun demikian, Anda masih dapat menggunakan NSCell subkelas NSTableCellView dan membuat baris dan kolom kustom.

Tampilan Tabel tidak menyimpan datanya sendiri, sebaliknya bergantung pada Sumber Data (NSTableViewDataSource) untuk menyediakan baris dan kolom yang diperlukan, sesuai kebutuhan.

Perilaku Tampilan Tabel dapat dikustomisasi dengan menyediakan subkelas Delegasi Tampilan Tabel (NSTableViewDelegate) untuk mendukung manajemen kolom tabel, ketik untuk memilih fungsionalitas, pemilihan dan pengeditan baris, pelacakan kustom, dan tampilan kustom untuk kolom dan baris individual.

Saat membuat Tampilan Tabel, Apple menyarankan hal berikut:

  • Perbolehkan pengguna untuk mengurutkan tabel dengan mengklik Header Kolom.
  • Buat Header Kolom yang merupakan kata benda atau frasa kata benda pendek yang menjelaskan data yang ditampilkan di kolom tersebut.

Untuk informasi selengkapnya, silakan lihat bagian Tampilan Konten dari Pedoman Antarmuka Manusia OS X Apple.

Membuat dan Memelihara Tampilan Tabel di Xcode

Saat Anda membuat aplikasi Xamarin.Mac Cocoa baru, Anda mendapatkan jendela kosong standar secara default. Jendela ini didefinisikan dalam file yang .storyboard secara otomatis disertakan dalam proyek. Untuk mengedit desain windows Anda, di Penjelajah Solusi, klik Main.storyboard dua kali file:

Memilih papan cerita utama

Ini akan membuka desain jendela di Penyusun Antarmuka Xcode:

Mengedit UI dalam Xcode

Ketik table ke dalam Kotak Pencarian Pemeriksa Pustaka untuk mempermudah menemukan kontrol Tampilan Tabel:

Memilih Tampilan Tabel dari Pustaka

Seret Tampilan Tabel ke Pengontrol Tampilan di Editor Antarmuka, buatlah mengisi area konten Pengontrol Tampilan dan atur ke tempatnya menyusut dan tumbuh dengan jendela di Editor Batasan:

Mengedit batasan

Pilih Tampilan Tabel di Hierarki Antarmuka dan properti berikut ini tersedia di Pemeriksa Atribut:

Cuplikan layar memperlihatkan properti yang tersedia di Pemeriksa Atribut.

  • Mode Konten - Memungkinkan Anda menggunakan Tampilan (NSView) atau Sel (NSCell) untuk menampilkan data dalam baris dan kolom. Dimulai dengan macOS 10.7, Anda harus menggunakan Tampilan.
  • Baris Grup Mengambang - Jika true, Tampilan Tabel akan menggambar sel yang dikelompokkan seolah-olah mengambang.
  • Kolom - Menentukan jumlah kolom yang ditampilkan.
  • Header - Jika true, kolom akan memiliki Header.
  • Menyusun ulang - Jika true, pengguna akan dapat menyeret menyusun ulang kolom dalam tabel.
  • Mengubah ukuran - Jika true, pengguna akan dapat menyeret Header kolom untuk mengubah ukuran kolom.
  • Ukuran Kolom - Mengontrol bagaimana tabel akan mengukur kolom secara otomatis.
  • Sorot - Mengontrol tipe penyorotan tabel yang digunakan saat sel dipilih.
  • Baris Alternatif - Jika true, pernah baris lain akan memiliki warna latar belakang yang berbeda.
  • Kisi Horizontal - Memilih tipe batas yang digambar di antara sel secara horizontal.
  • Kisi Vertikal - Memilih tipe batas yang digambar di antara sel secara vertikal.
  • Warna Kisi - Mengatur warna batas sel.
  • Latar Belakang - Mengatur warna latar belakang sel.
  • Pilihan - Memungkinkan Anda mengontrol bagaimana pengguna dapat memilih sel dalam tabel sebagai:
    • Beberapa - Jika true, pengguna dapat memilih beberapa baris dan kolom.
    • Kolom - Jika true,pengguna dapat memilih kolom.
    • Ketik Pilih - Jika true, pengguna dapat mengetik karakter untuk memilih baris.
    • Kosong - Jika true, pengguna tidak diperlukan untuk memilih baris atau kolom, tabel memungkinkan tidak ada pilihan sama sekali.
  • Simpan Otomatis - Nama yang disimpan dalam format tabel secara otomatis.
  • Informasi Kolom - Jika true, urutan dan lebar kolom akan disimpan secara otomatis.
  • Pemisah Baris - Pilih bagaimana sel menangani pemisah garis.
  • Memotong Baris Terakhir Terlihat - Jika true, sel akan dipotong dalam data tidak dapat pas di dalam batasnya.

Penting

Kecuali Anda mempertahankan aplikasi Xamarin.Mac warisan, NSView Tampilan Tabel berbasis harus digunakan melalui NSCell Tampilan Tabel berbasis. NSCell dianggap warisan dan mungkin tidak didukung ke depannya.

Pilih Kolom Tabel di Hierarki Antarmuka dan properti berikut ini tersedia di Pemeriksa Atribut:

Cuplikan layar memperlihatkan properti yang tersedia untuk Kolom Tabel di Pemeriksa Atribut.

  • Judul - Mengatur judul kolom.
  • Perataan - Atur perataan teks dalam sel.
  • Font Judul - Memilih font untuk teks Header sel.
  • Urutkan Kunci - Apakah kunci digunakan untuk mengurutkan data dalam kolom. Biarkan kosong jika pengguna tidak dapat mengurutkan kolom ini.
  • Pemilih- Apakah Tindakan digunakan untuk melakukan pengurutan. Biarkan kosong jika pengguna tidak dapat mengurutkan kolom ini.
  • Urutan - Adalah urutan pengurutan untuk data kolom.
  • Mengubah ukuran - Memilih jenis perubahan ukuran untuk kolom.
  • Dapat diedit - Jika true, pengguna dapat mengedit sel dalam tabel berbasis sel.
  • Tersembunyi - Jika true, kolom disembunyikan.

Anda juga dapat mengubah ukuran kolom dengan menyeret handelnya (berpusat secara vertikal di sisi kanan kolom) kiri atau kanan.

Mari kita pilih setiap Kolom dalam Tampilan Tabel kita dan beri kolom pertama JudulProduct dan yang Detailskedua .

Pilih Tampilan Sel Tabel (NSTableViewCell) di Hierarki Antarmuka dan properti berikut ini tersedia di Pemeriksa Atribut:

Cuplikan layar memperlihatkan properti yang tersedia untuk Tampilan Sel Tabel di Pemeriksa Atribut.

Ini adalah semua properti tampilan standar. Anda juga memiliki opsi untuk mengubah ukuran baris untuk kolom ini di sini.

Pilih Sel Tampilan Tabel (secara default, ini adalah NSTextField) dalam Hierarki Antarmuka dan properti berikut ini tersedia di Pemeriksa Atribut:

Cuplikan layar memperlihatkan properti yang tersedia untuk Sel Tampilan Tabel di Pemeriksa Atribut.

Anda akan memiliki semua properti bidang teks standar untuk diatur di sini. Secara default, Bidang Teks standar digunakan untuk menampilkan data untuk sel dalam kolom.

Pilih Tampilan Sel Tabel (NSTableFieldCell) di Hierarki Antarmuka dan properti berikut ini tersedia di Pemeriksa Atribut:

Cuplikan layar memperlihatkan properti yang tersedia untuk Sel Tampilan Tabel yang berbeda di Pemeriksa Atribut.

Pengaturan yang paling penting di sini adalah:

  • Tata Letak - Pilih bagaimana sel dalam kolom ini ditata.
  • Menggunakan Mode Garis Tunggal - Jika true, sel dibatasi pada satu baris.
  • Lebar Tata Letak Runtime Pertama - Jika true, sel akan lebih memilih lebar yang diatur untuknya (baik secara manual atau otomatis) saat ditampilkan saat pertama kali aplikasi dijalankan.
  • Tindakan - Mengontrol kapan Tindakan Edit dikirim untuk sel.
  • Perilaku - Menentukan apakah sel dapat dipilih atau dapat diedit.
  • Teks Kaya - Jika true, sel dapat menampilkan teks yang diformat dan ditata.
  • Batalkan - Jika true, sel bertanggung jawab atas perilaku batalkan.

Pilih Tampilan Sel Tabel (NSTableFieldCell) di bagian bawah Kolom Tabel di Hierarki Antarmuka:

Memilih Tampilan Sel Tabel

Ini memungkinkan Anda mengedit Tampilan Sel Tabel yang digunakan sebagai Pola dasar untuk semua sel yang dibuat untuk kolom tertentu.

Menambahkan Tindakan dan Outlet

Sama seperti kontrol Antarmuka Pengguna Kakao lainnya, kita perlu mengekspos Tampilan Tabel kita dan kolom dan sel ke kode C# menggunakan Tindakan dan Outlet (berdasarkan fungsionalitas yang diperlukan).

Prosesnya sama untuk elemen Tampilan Tabel apa pun yang ingin kita ekspos:

  1. Beralih ke Editor Asisten dan pastikan bahwa ViewController.h file dipilih:

    Editor Asisten

  2. Pilih Tampilan Tabel dari Hierarki Antarmuka, klik kontrol dan seret ke ViewController.h file.

  3. Buat Outlet untuk Tampilan Tabel yang disebut ProductTable:

    Cuplikan layar memperlihatkan koneksi Outlet yang dibuat untuk Tampilan Tabel bernama ProductTable.

  4. Buat Outlet untuk kolom tabel juga disebut ProductColumn dan DetailsColumn:

    Cuplikan layar memperlihatkan koneksi Outlet yang dibuat untuk Tampilan Tabel lainnya.

  5. Simpan perubahan Anda dan kembali ke Visual Studio untuk Mac untuk disinkronkan dengan Xcode.

Selanjutnya, kita akan menulis kode yang menampilkan beberapa data untuk tabel saat aplikasi dijalankan.

Mengisi Tampilan Tabel

Dengan Tampilan Tabel kami yang dirancang dalam Penyusun Antarmuka dan diekspos melalui Outlet, selanjutnya kita perlu membuat kode C# untuk mengisinya.

Pertama, mari kita buat kelas baru Product untuk menyimpan informasi untuk masing-masing baris. Di Penjelajah Solusi, klik kanan Proyek dan pilih Tambahkan>File Baru... Pilih Kelas Kosong Umum>, masukkan Product untuk Nama dan klik tombol Baru:

Membuat kelas kosong

Product.cs Buat file terlihat seperti berikut ini:

using System;

namespace MacTables
{
  public class Product
  {
    #region Computed Properties
    public string Title { get; set;} = "";
    public string Description { get; set;} = "";
    #endregion

    #region Constructors
    public Product ()
    {
    }

    public Product (string title, string description)
    {
      this.Title = title;
      this.Description = description;
    }
    #endregion
  }
}

Selanjutnya, kita perlu membuat subkelas NSTableDataSource untuk menyediakan data untuk tabel kita seperti yang diminta. Di Penjelajah Solusi, klik kanan Proyek dan pilih Tambahkan>File Baru... Pilih Kelas Kosong Umum>, masukkan ProductTableDataSource untuk Nama dan klik tombol Baru.

ProductTableDataSource.cs Edit file dan buat terlihat seperti berikut ini:

using System;
using AppKit;
using CoreGraphics;
using Foundation;
using System.Collections;
using System.Collections.Generic;

namespace MacTables
{
  public class ProductTableDataSource : NSTableViewDataSource
  {
    #region Public Variables
    public List<Product> Products = new List<Product>();
    #endregion

    #region Constructors
    public ProductTableDataSource ()
    {
    }
    #endregion

    #region Override Methods
    public override nint GetRowCount (NSTableView tableView)
    {
      return Products.Count;
    }
    #endregion
  }
}

Kelas ini memiliki penyimpanan untuk item Tampilan Tabel kami dan mengambil alih GetRowCount untuk mengembalikan jumlah baris dalam tabel.

Akhirnya, kita perlu membuat subkelas NSTableDelegate untuk memberikan perilaku untuk tabel kita. Di Penjelajah Solusi, klik kanan Proyek dan pilih Tambahkan>File Baru... Pilih Kelas Kosong Umum>, masukkan ProductTableDelegate untuk Nama dan klik tombol Baru.

ProductTableDelegate.cs Edit file dan buat terlihat seperti berikut ini:

using System;
using AppKit;
using CoreGraphics;
using Foundation;
using System.Collections;
using System.Collections.Generic;

namespace MacTables
{
  public class ProductTableDelegate: NSTableViewDelegate
  {
    #region Constants
    private const string CellIdentifier = "ProdCell";
    #endregion

    #region Private Variables
    private ProductTableDataSource DataSource;
    #endregion

    #region Constructors
    public ProductTableDelegate (ProductTableDataSource datasource)
    {
      this.DataSource = datasource;
    }
    #endregion

    #region Override Methods
    public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
    {
      // This pattern allows you reuse existing views when they are no-longer in use.
      // If the returned view is null, you instance up a new view
      // If a non-null view is returned, you modify it enough to reflect the new data
      NSTextField view = (NSTextField)tableView.MakeView (CellIdentifier, this);
      if (view == null) {
        view = new NSTextField ();
        view.Identifier = CellIdentifier;
        view.BackgroundColor = NSColor.Clear;
        view.Bordered = false;
        view.Selectable = false;
        view.Editable = false;
      }

      // Setup view based on the column selected
      switch (tableColumn.Title) {
      case "Product":
        view.StringValue = DataSource.Products [(int)row].Title;
        break;
      case "Details":
        view.StringValue = DataSource.Products [(int)row].Description;
        break;
      }

      return view;
    }
    #endregion
  }
}

Ketika kita membuat instans ProductTableDelegate, kita juga meneruskan instans ProductTableDataSource yang menyediakan data untuk tabel. Metode GetViewForItem ini bertanggung jawab untuk mengembalikan tampilan (data) untuk menampilkan sel untuk kolom dan baris beri. Jika memungkinkan, tampilan yang ada akan digunakan kembali untuk menampilkan sel, jika bukan tampilan baru harus dibuat.

Untuk mengisi tabel, mari kita edit ViewController.cs file dan buat AwakeFromNib metode terlihat seperti berikut ini:

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

  // Create the Product Table Data Source and populate it
  var DataSource = new ProductTableDataSource ();
  DataSource.Products.Add (new Product ("Xamarin.iOS", "Allows you to develop native iOS Applications in C#"));
  DataSource.Products.Add (new Product ("Xamarin.Android", "Allows you to develop native Android Applications in C#"));
  DataSource.Products.Add (new Product ("Xamarin.Mac", "Allows you to develop Mac native Applications in C#"));

  // Populate the Product Table
  ProductTable.DataSource = DataSource;
  ProductTable.Delegate = new ProductTableDelegate (DataSource);
}

Jika kita menjalankan aplikasi, berikut ini ditampilkan:

Cuplikan layar memperlihatkan jendela bernama Tabel Produk dengan tiga entri.

Mengurutkan menurut Kolom

Mari kita izinkan pengguna untuk mengurutkan data dalam tabel dengan mengklik Header Kolom. Pertama, klik Main.storyboard dua kali file untuk membukanya untuk pengeditan di Interface Builder. Product Pilih kolom, masukkan Title untuk Kunci Pengurutan, compare: untuk Pemilihdan pilih Ascending untuk Pesanan:

Cuplikan layar memperlihatkan Penyusun Antarmuka tempat Anda dapat mengatur kunci pengurutan untuk kolom Produk.

Details Pilih kolom, masukkan Description untuk Kunci Pengurutan, compare: untuk Pemilihdan pilih Ascending untuk Pesanan:

Cuplikan layar memperlihatkan Penyusun Antarmuka tempat Anda dapat mengatur kunci pengurutan untuk kolom Detail.

Simpan perubahan Anda dan kembali ke Visual Studio untuk Mac untuk disinkronkan dengan Xcode.

Sekarang mari kita edit ProductTableDataSource.cs file dan tambahkan metode berikut:

public void Sort(string key, bool ascending) {

  // Take action based on key
  switch (key) {
  case "Title":
    if (ascending) {
      Products.Sort ((x, y) => x.Title.CompareTo (y.Title));
    } else {
      Products.Sort ((x, y) => -1 * x.Title.CompareTo (y.Title));
    }
    break;
  case "Description":
    if (ascending) {
      Products.Sort ((x, y) => x.Description.CompareTo (y.Description));
    } else {
      Products.Sort ((x, y) => -1 * x.Description.CompareTo (y.Description));
    }
    break;
  }

}

public override void SortDescriptorsChanged (NSTableView tableView, NSSortDescriptor[] oldDescriptors)
{
  // Sort the data
  if (oldDescriptors.Length > 0) {
    // Update sort
    Sort (oldDescriptors [0].Key, oldDescriptors [0].Ascending);
  } else {
    // Grab current descriptors and update sort
    NSSortDescriptor[] tbSort = tableView.SortDescriptors;
    Sort (tbSort[0].Key, tbSort[0].Ascending);
  }

  // Refresh table
  tableView.ReloadData ();
}

Metode ini Sort memungkinkan kita untuk mengurutkan data di Sumber Data berdasarkan bidang kelas tertentu Product dalam urutan naik atau turun. Metode yang ditimpa SortDescriptorsChanged akan dipanggil setiap kali penggunaan mengklik Judul Kolom. Ini akan diteruskan nilai Kunci yang kita tetapkan di Penyusun Antarmuka dan urutan pengurutan untuk kolom tersebut.

Jika kita menjalankan aplikasi dan mengklik Header Kolom, baris akan diurutkan menurut kolom tersebut:

Contoh eksekusi aplikasi

Pilihan Baris

Jika Anda ingin mengizinkan pengguna memilih satu baris, klik Main.storyboard dua kali file untuk membukanya untuk pengeditan di Penyusun Antarmuka. Pilih Tampilan Tabel di Hierarki Antarmuka dan kosongkan kotak centang Beberapa di Pemeriksa Atribut:

Cuplikan layar memperlihatkan Penyusun Antarmuka tempat Anda dapat memilih Beberapa di Pemeriksa Atribut.

Simpan perubahan Anda dan kembali ke Visual Studio untuk Mac untuk disinkronkan dengan Xcode.

Selanjutnya, edit ProductTableDelegate.cs file dan tambahkan metode berikut:

public override bool ShouldSelectRow (NSTableView tableView, nint row)
{
  return true;
}

Ini akan memungkinkan pengguna untuk memilih baris tunggal apa pun dalam Tampilan Tabel. Kembali false untuk ShouldSelectRow baris apa pun yang tidak Anda inginkan agar pengguna dapat memilih atau false untuk setiap baris jika Anda tidak ingin pengguna dapat memilih baris apa pun.

Tampilan Tabel (NSTableView) berisi metode berikut untuk bekerja dengan pemilihan baris:

  • DeselectRow(nint) - Membatalkan pilihan baris yang diberikan dalam tabel.
  • SelectRow(nint,bool) - Memilih baris yang diberikan. Teruskan false parameter kedua untuk memilih hanya satu baris pada satu waktu.
  • SelectedRow - Mengembalikan baris saat ini yang dipilih dalam tabel.
  • IsRowSelected(nint) - Mengembalikan true jika baris yang diberikan dipilih.

Pilihan Beberapa Baris

Jika Anda ingin mengizinkan pengguna memilih beberapa baris, klik Main.storyboard dua kali file untuk membukanya untuk pengeditan di Penyusun Antarmuka. Pilih Tampilan Tabel di Hierarki Antarmuka dan centang kotak Beberapa di Pemeriksa Atribut:

Cuplikan layar memperlihatkan Penyusun Antarmuka tempat Anda dapat memilih Beberapa untuk mengizinkan pilihan beberapa baris.

Simpan perubahan Anda dan kembali ke Visual Studio untuk Mac untuk disinkronkan dengan Xcode.

Selanjutnya, edit ProductTableDelegate.cs file dan tambahkan metode berikut:

public override bool ShouldSelectRow (NSTableView tableView, nint row)
{
  return true;
}

Ini akan memungkinkan pengguna untuk memilih baris tunggal apa pun dalam Tampilan Tabel. Kembali false untuk ShouldSelectRow baris apa pun yang tidak Anda inginkan agar pengguna dapat memilih atau false untuk setiap baris jika Anda tidak ingin pengguna dapat memilih baris apa pun.

Tampilan Tabel (NSTableView) berisi metode berikut untuk bekerja dengan pemilihan baris:

  • DeselectAll(NSObject) - Membatalkan pilihan semua baris dalam tabel. Gunakan this untuk parameter pertama yang akan dikirim dalam objek yang melakukan pemilihan.
  • DeselectRow(nint) - Membatalkan pilihan baris yang diberikan dalam tabel.
  • SelectAll(NSobject) - Memilih semua baris dalam tabel. Gunakan this untuk parameter pertama yang akan dikirim dalam objek yang melakukan pemilihan.
  • SelectRow(nint,bool) - Memilih baris yang diberikan. Teruskan untuk parameter kedua hapus pilihan dan pilih hanya satu baris, teruskan falsetrue untuk memperluas pilihan dan sertakan baris ini.
  • SelectRows(NSIndexSet,bool) - Memilih set baris yang diberikan. Teruskan untuk parameter kedua hapus pilihan dan pilih hanya baris ini, teruskan falsetrue untuk memperluas pilihan dan sertakan baris ini.
  • SelectedRow - Mengembalikan baris saat ini yang dipilih dalam tabel.
  • SelectedRows - Mengembalikan yang NSIndexSet berisi indeks baris yang dipilih.
  • SelectedRowCount - Mengembalikan jumlah baris yang dipilih.
  • IsRowSelected(nint) - Mengembalikan true jika baris yang diberikan dipilih.

Ketik untuk Memilih Baris

Jika Anda ingin mengizinkan pengguna mengetik karakter dengan Tampilan Tabel dipilih dan memilih baris pertama yang memiliki karakter tersebut Main.storyboard , klik dua kali file untuk membukanya untuk pengeditan di Penyusun Antarmuka. Pilih Tampilan Tabel di Hierarki Antarmuka dan centang kotak centang Pilih Jenis di Pemeriksa Atribut:

Mengatur jenis pilihan

Simpan perubahan Anda dan kembali ke Visual Studio untuk Mac untuk disinkronkan dengan Xcode.

Sekarang mari kita edit ProductTableDelegate.cs file dan tambahkan metode berikut:

public override nint GetNextTypeSelectMatch (NSTableView tableView, nint startRow, nint endRow, string searchString)
{
  nint row = 0;
  foreach(Product product in DataSource.Products) {
    if (product.Title.Contains(searchString)) return row;

    // Increment row counter
    ++row;
  }

  // If not found select the first row
  return 0;
}

Metode GetNextTypeSelectMatch mengambil yang diberikan searchString dan mengembalikan baris pertama Product yang memiliki string tersebut di dalamnya adalah Title.

Jika kita menjalankan aplikasi dan mengetik karakter, baris dipilih:

Cuplikan layar memperlihatkan hasil menjalankan aplikasi.

Menyusun Ulang Kolom

Jika Anda ingin mengizinkan pengguna untuk menyeret urutkan ulang kolom dalam Tampilan Tabel, klik Main.storyboard dua kali file untuk membukanya untuk pengeditan di Penyusun Antarmuka. Pilih Tampilan Tabel di Hierarki Antarmuka dan centang kotak Susun Ulang di Pemeriksa Atribut:

Cuplikan layar memperlihatkan Penyusun Antarmuka tempat Anda dapat memilih Reodering di Pemeriksa Atribut.

Jika kita memberikan nilai untuk properti Simpan Otomatis dan memeriksa bidang Informasi Kolom, setiap perubahan yang kita buat pada tata letak tabel akan secara otomatis disimpan untuk kita dan dipulihkan saat aplikasi dijalankan berikutnya.

Simpan perubahan Anda dan kembali ke Visual Studio untuk Mac untuk disinkronkan dengan Xcode.

Sekarang mari kita edit ProductTableDelegate.cs file dan tambahkan metode berikut:

public override bool ShouldReorder (NSTableView tableView, nint columnIndex, nint newColumnIndex)
{
  return true;
}

Metode ShouldReorder harus kembali true untuk kolom apa pun yang ingin diizinkan untuk diseret diurutkan ulang ke dalam newColumnIndex, yang lain mengembalikan false;

Jika kita menjalankan aplikasi, kita dapat menyeret Header Kolom untuk menyusun ulang kolom kita:

Contoh kolom yang diurutkan ulang

Mengedit Sel

Jika Anda ingin mengizinkan pengguna mengedit nilai untuk sel tertentu, edit ProductTableDelegate.cs file dan ubah GetViewForItem metode sebagai berikut:

public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
{
  // This pattern allows you reuse existing views when they are no-longer in use.
  // If the returned view is null, you instance up a new view
  // If a non-null view is returned, you modify it enough to reflect the new data
  NSTextField view = (NSTextField)tableView.MakeView (tableColumn.Title, this);
  if (view == null) {
    view = new NSTextField ();
    view.Identifier = tableColumn.Title;
    view.BackgroundColor = NSColor.Clear;
    view.Bordered = false;
    view.Selectable = false;
    view.Editable = true;

    view.EditingEnded += (sender, e) => {

      // Take action based on type
      switch(view.Identifier) {
      case "Product":
        DataSource.Products [(int)view.Tag].Title = view.StringValue;
        break;
      case "Details":
        DataSource.Products [(int)view.Tag].Description = view.StringValue;
        break;
      }
    };
  }

  // Tag view
  view.Tag = row;

  // Setup view based on the column selected
  switch (tableColumn.Title) {
  case "Product":
    view.StringValue = DataSource.Products [(int)row].Title;
    break;
  case "Details":
    view.StringValue = DataSource.Products [(int)row].Description;
    break;
  }

  return view;
}

Sekarang jika kita menjalankan aplikasi, pengguna dapat mengedit sel dalam Tampilan Tabel:

Contoh pengeditan sel

Menggunakan Gambar dalam Tampilan Tabel

Untuk menyertakan gambar sebagai bagian dari sel dalam NSTableView, Anda harus mengubah cara data dikembalikan oleh metode Tampilan NSTableViewDelegate'sGetViewForItem Tabel untuk menggunakan NSTableCellView alih-alih yang umum NSTextField. Contohnya:

public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
{

  // This pattern allows you reuse existing views when they are no-longer in use.
  // If the returned view is null, you instance up a new view
  // If a non-null view is returned, you modify it enough to reflect the new data
  NSTableCellView view = (NSTableCellView)tableView.MakeView (tableColumn.Title, this);
  if (view == null) {
    view = new NSTableCellView ();
    if (tableColumn.Title == "Product") {
      view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
      view.AddSubview (view.ImageView);
      view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
    } else {
      view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
    }
    view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;
    view.AddSubview (view.TextField);
    view.Identifier = tableColumn.Title;
    view.TextField.BackgroundColor = NSColor.Clear;
    view.TextField.Bordered = false;
    view.TextField.Selectable = false;
    view.TextField.Editable = true;

    view.TextField.EditingEnded += (sender, e) => {

      // Take action based on type
      switch(view.Identifier) {
      case "Product":
        DataSource.Products [(int)view.TextField.Tag].Title = view.TextField.StringValue;
        break;
      case "Details":
        DataSource.Products [(int)view.TextField.Tag].Description = view.TextField.StringValue;
        break;
      }
    };
  }

  // Tag view
  view.TextField.Tag = row;

  // Setup view based on the column selected
  switch (tableColumn.Title) {
  case "Product":
    view.ImageView.Image = NSImage.ImageNamed ("tags.png");
    view.TextField.StringValue = DataSource.Products [(int)row].Title;
    break;
  case "Details":
    view.TextField.StringValue = DataSource.Products [(int)row].Description;
    break;
  }

  return view;
}

Untuk informasi selengkapnya, silakan lihat bagian Menggunakan Gambar dengan Tampilan Tabel dari dokumentasi Bekerja dengan Gambar kami.

Menambahkan Tombol Hapus ke Baris

Berdasarkan persyaratan aplikasi Anda, mungkin ada kesempatan di mana Anda perlu menyediakan tombol tindakan untuk setiap baris dalam tabel. Sebagai contohnya, mari kita perluas contoh Tampilan Tabel yang dibuat di atas untuk menyertakan tombol Hapus pada setiap baris.

Pertama, edit Main.storyboard di Penyusun Antarmuka Xcode, pilih Tampilan Tabel dan tingkatkan jumlah kolom menjadi tiga (3). Selanjutnya, ubah Judul kolom baru menjadi Action:

Mengedit nama kolom

Simpan perubahan ke Storyboard dan kembali ke Visual Studio untuk Mac untuk menyinkronkan perubahan.

Selanjutnya, edit ViewController.cs file dan tambahkan metode publik berikut:

public void ReloadTable ()
{
  ProductTable.ReloadData ();
}

Dalam file yang sama, ubah pembuatan Delegasi Tampilan Tabel baru di dalam ViewDidLoad metode sebagai berikut:

// Populate the Product Table
ProductTable.DataSource = DataSource;
ProductTable.Delegate = new ProductTableDelegate (this, DataSource);

Sekarang, edit ProductTableDelegate.cs file untuk menyertakan koneksi privat ke Pengontrol Tampilan dan untuk mengambil pengontrol sebagai parameter saat membuat instans baru delegasi:

#region Private Variables
private ProductTableDataSource DataSource;
private ViewController Controller;
#endregion

#region Constructors
public ProductTableDelegate (ViewController controller, ProductTableDataSource datasource)
{
  this.Controller = controller;
  this.DataSource = datasource;
}
#endregion

Selanjutnya, tambahkan metode privat baru berikut ke kelas :

private void ConfigureTextField (NSTableCellView view, nint row)
{
  // Add to view
  view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;
  view.AddSubview (view.TextField);

  // Configure
  view.TextField.BackgroundColor = NSColor.Clear;
  view.TextField.Bordered = false;
  view.TextField.Selectable = false;
  view.TextField.Editable = true;

  // Wireup events
  view.TextField.EditingEnded += (sender, e) => {

    // Take action based on type
    switch (view.Identifier) {
    case "Product":
      DataSource.Products [(int)view.TextField.Tag].Title = view.TextField.StringValue;
      break;
    case "Details":
      DataSource.Products [(int)view.TextField.Tag].Description = view.TextField.StringValue;
      break;
    }
  };

  // Tag view
  view.TextField.Tag = row;
}

Ini mengambil semua konfigurasi Tampilan Teks yang sebelumnya sedang dilakukan dalam GetViewForItem metode dan menempatkannya dalam satu lokasi yang dapat dipanggil (karena kolom terakhir tabel tidak menyertakan Tampilan Teks tetapi Tombol).

Terakhir, edit GetViewForItem metode dan buat terlihat seperti berikut ini:

public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
{

  // This pattern allows you reuse existing views when they are no-longer in use.
  // If the returned view is null, you instance up a new view
  // If a non-null view is returned, you modify it enough to reflect the new data
  NSTableCellView view = (NSTableCellView)tableView.MakeView (tableColumn.Title, this);
  if (view == null) {
    view = new NSTableCellView ();

    // Configure the view
    view.Identifier = tableColumn.Title;

    // Take action based on title
    switch (tableColumn.Title) {
    case "Product":
      view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
      view.AddSubview (view.ImageView);
      view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
      ConfigureTextField (view, row);
      break;
    case "Details":
      view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
      ConfigureTextField (view, row);
      break;
    case "Action":
      // Create new button
      var button = new NSButton (new CGRect (0, 0, 81, 16));
      button.SetButtonType (NSButtonType.MomentaryPushIn);
      button.Title = "Delete";
      button.Tag = row;

      // Wireup events
      button.Activated += (sender, e) => {
        // Get button and product
        var btn = sender as NSButton;
        var product = DataSource.Products [(int)btn.Tag];

        // Configure alert
        var alert = new NSAlert () {
          AlertStyle = NSAlertStyle.Informational,
          InformativeText = $"Are you sure you want to delete {product.Title}? This operation cannot be undone.",
          MessageText = $"Delete {product.Title}?",
        };
        alert.AddButton ("Cancel");
        alert.AddButton ("Delete");
        alert.BeginSheetForResponse (Controller.View.Window, (result) => {
          // Should we delete the requested row?
          if (result == 1001) {
            // Remove the given row from the dataset
            DataSource.Products.RemoveAt((int)btn.Tag);
            Controller.ReloadTable ();
          }
        });
      };

      // Add to view
      view.AddSubview (button);
      break;
    }

  }

  // Setup view based on the column selected
  switch (tableColumn.Title) {
  case "Product":
    view.ImageView.Image = NSImage.ImageNamed ("tag.png");
    view.TextField.StringValue = DataSource.Products [(int)row].Title;
    view.TextField.Tag = row;
    break;
  case "Details":
    view.TextField.StringValue = DataSource.Products [(int)row].Description;
    view.TextField.Tag = row;
    break;
  case "Action":
    foreach (NSView subview in view.Subviews) {
      var btn = subview as NSButton;
      if (btn != null) {
        btn.Tag = row;
      }
    }
    break;
  }

  return view;
}

Mari kita lihat beberapa bagian kode ini secara lebih rinci. Pertama, jika tindakan baru NSTableViewCell sedang dibuat diambil berdasarkan nama Kolom. Untuk dua kolom pertama (Produk dan Detail), metode baru ConfigureTextField dipanggil.

Untuk kolom Tindakan, baru NSButton dibuat dan ditambahkan ke Sel sebagai Sub Tampilan:

// Create new button
var button = new NSButton (new CGRect (0, 0, 81, 16));
button.SetButtonType (NSButtonType.MomentaryPushIn);
button.Title = "Delete";
button.Tag = row;
...

// Add to view
view.AddSubview (button);

Properti Tombol Tag digunakan untuk menahan jumlah Baris yang saat ini sedang diproses. Nomor ini akan digunakan nanti ketika pengguna meminta baris untuk dihapus dalam peristiwa Tombol Activated :

// Wireup events
button.Activated += (sender, e) => {
  // Get button and product
  var btn = sender as NSButton;
  var product = DataSource.Products [(int)btn.Tag];

  // Configure alert
  var alert = new NSAlert () {
    AlertStyle = NSAlertStyle.Informational,
    InformativeText = $"Are you sure you want to delete {product.Title}? This operation cannot be undone.",
    MessageText = $"Delete {product.Title}?",
  };
  alert.AddButton ("Cancel");
  alert.AddButton ("Delete");
  alert.BeginSheetForResponse (Controller.View.Window, (result) => {
    // Should we delete the requested row?
    if (result == 1001) {
      // Remove the given row from the dataset
      DataSource.Products.RemoveAt((int)btn.Tag);
      Controller.ReloadTable ();
    }
  });
};

Di awal penanganan aktivitas, kita mendapatkan tombol dan produk yang ada di baris tabel yang diberikan. Kemudian Pemberitahuan disajikan kepada pengguna yang mengonfirmasi penghapusan baris. Jika pengguna memilih untuk menghapus baris, baris yang diberikan dihapus dari Sumber Data dan tabel dimuat ulang:

// Remove the given row from the dataset
DataSource.Products.RemoveAt((int)btn.Tag);
Controller.ReloadTable ();

Terakhir, jika Sel Tampilan Tabel sedang digunakan kembali alih-alih dibuat baru, kode berikut mengonfigurasinya berdasarkan Kolom yang sedang diproses:

// Setup view based on the column selected
switch (tableColumn.Title) {
case "Product":
  view.ImageView.Image = NSImage.ImageNamed ("tag.png");
  view.TextField.StringValue = DataSource.Products [(int)row].Title;
  view.TextField.Tag = row;
  break;
case "Details":
  view.TextField.StringValue = DataSource.Products [(int)row].Description;
  view.TextField.Tag = row;
  break;
case "Action":
  foreach (NSView subview in view.Subviews) {
    var btn = subview as NSButton;
    if (btn != null) {
      btn.Tag = row;
    }
  }
  break;
}

Untuk kolom Tindakan, semua Sub Tampilan dipindai hingga NSButton ditemukan, maka Tag properti diperbarui untuk mengarah ke Baris saat ini.

Dengan perubahan ini di tempat, ketika aplikasi dijalankan setiap baris akan memiliki tombol Hapus :

Tampilan tabel dengan tombol penghapusan

Saat pengguna mengklik tombol Hapus , pemberitahuan akan ditampilkan yang meminta mereka untuk menghapus Baris yang diberikan:

Pemberitahuan hapus baris

Jika pengguna memilih hapus, baris akan dihapus dan tabel akan digambar ulang:

Tabel setelah baris dihapus

Tampilan Tabel Pengikatan Data

Dengan menggunakan teknik Key-Value Coding dan Data Binding di aplikasi Xamarin.Mac, Anda dapat sangat mengurangi jumlah kode yang harus Anda tulis dan pertahankan untuk mengisi dan bekerja dengan elemen UI. Anda juga memiliki manfaat untuk memisahkan lebih lanjut data cadangan Anda (Model Data) dari Antarmuka Pengguna ujung depan Anda (Model-View-Controller), yang mengarah ke desain aplikasi yang lebih mudah dipertahankan dan lebih fleksibel.

Key-Value Coding (KVC) adalah mekanisme untuk mengakses properti objek secara tidak langsung, menggunakan kunci (string yang diformat khusus) untuk mengidentifikasi properti alih-alih mengaksesnya melalui variabel instans atau metode aksesor (get/set). Dengan menerapkan aksesor yang sesuai dengan Key-Value Coding di aplikasi Xamarin.Mac Anda, Anda mendapatkan akses ke fitur macOS lain seperti Key-Value Observing (KVO), Pengikatan Data, Data Inti, Pengikatan kakao, dan kemampuan skrip.

Untuk informasi selengkapnya, silakan lihat bagian Pengikatan Data Tampilan Tabel dari dokumentasi Pengikatan Data dan Pengodatan Nilai Kunci kami.

Ringkasan

Artikel ini telah melihat secara rinci tentang bekerja dengan Tampilan Tabel dalam aplikasi Xamarin.Mac. Kami melihat berbagai jenis dan penggunaan Tampilan Tabel, cara membuat dan memelihara Tampilan Tabel di Penyusun Antarmuka Xcode dan cara bekerja dengan Tampilan Tabel dalam kode C#.