Tabulková zobrazení v Xamarin. Mac

Tento článek popisuje práci s zobrazeními tabulek v aplikaci Xamarin. Mac. Popisuje vytváření zobrazení tabulek v Xcode a Interface Builder a interakci s nimi v kódu.

Při práci s C# a .NET v aplikaci Xamarin. Mac máte přístup ke stejným tabulkovým zobrazením, v nichž vývojář pracuje Objective-C a Objective-C . Protože se Xamarin. Mac integruje přímo s Xcode, můžete použít Interface Builder Xcode k vytváření a údržbě zobrazení tabulek (nebo je případně můžete vytvořit přímo v kódu C#).

Tabulkové zobrazení zobrazuje data v tabulkovém formátu, který obsahuje jeden nebo více sloupců s informacemi ve více řádcích. V závislosti na typu vytvářeného zobrazení tabulky může uživatel řadit podle sloupců, měnit uspořádání sloupců, přidávat sloupce, odebírat sloupce nebo upravovat data obsažená v tabulce.

Ukázková tabulka

V tomto článku se seznámíte se základy práce s zobrazeními tabulek v aplikaci Xamarin. Mac. Důrazně doporučujeme, abyste nejprve pracovali v článku Hello, Mac , konkrétně v částech Úvod k Xcode a Interface Builder a akcím a akcím , které se týkají klíčových konceptů a technik, které v tomto článku budeme používat.

Můžete se podívat i na část dokumentu s dalšími Exposing C# classes / methods to Objective-CExposing C# classes / methods to Objective-C a vysvětluje RegisterExport příkazy a používané k navýšení tříd jazyka C# do Objective-C objektů a prvků uživatelského rozhraní.

Úvod do tabulkových zobrazení

Tabulkové zobrazení zobrazuje data v tabulkovém formátu, který obsahuje jeden nebo více sloupců s informacemi ve více řádcích. Tabulková zobrazení se zobrazují v zobrazeních posunu ( NSScrollView ) a začínají v macOS 10,7, můžete použít NSView místo buněk ( NSCell ) k zobrazení řádků a sloupců. To však můžete i nadále používat NSCell , obvykle podtřídou NSTableCellView a vytvářet vlastní řádky a sloupce.

Tabulkové zobrazení neukládá vlastní data, místo toho se spoléhá na zdroj dat ( NSTableViewDataSource ), který poskytuje požadované řádky a sloupce podle potřeby.

Chování zobrazení tabulky lze přizpůsobit poskytnutím podtřídy delegáta zobrazení tabulky ( NSTableViewDelegate ) pro podporu správy sloupců tabulky, zadáním možnosti výběru funkcí, výběru řádků a úprav, vlastního sledování a vlastních zobrazení pro jednotlivé sloupce a řádky.

Při vytváření zobrazení tabulek společnost Apple navrhuje následující:

  • Umožní uživateli, aby tabulku seřadil kliknutím na záhlaví sloupců.
  • Vytvořte záhlaví sloupců, která jsou podstatná, nebo krátké podstatné fráze, které popisují data zobrazená v tomto sloupci.

Další informace najdete v části věnované zobrazení obsahu v tématu základní informace o rozhraních Apple OS X.

Vytváření a správa zobrazení tabulek v Xcode

Když vytvoříte novou aplikaci Xamarin. Mac kakaa, ve výchozím nastavení se zobrazí standardní prázdné okno. Tato okna jsou definována v souboru, který je .storyboard automaticky zahrnutý v projektu. Chcete-li upravit návrh systému Windows, v Průzkumník řešenídvakrát klikněte na soubor:

Výběr hlavního scénáře

Tím se otevře návrh okna Interface Builder Xcode:

Úprava uživatelského rozhraní v Xcode

Zadejte table do vyhledávacího pole v table , aby bylo snazší najít ovládací prvky zobrazení tabulky:

Výběr zobrazení tabulky z knihovny

Přetáhněte zobrazení tabulky do kontroleru zobrazení v editoru rozhraní, vyplněním oblasti obsahu kontroleru zobrazení a jeho nastavením na místo, kde se zmenší a rozroste pomocí okna v editoru omezení:

Omezení úprav

Vyberte zobrazení tabulky v hierarchii rozhraní a v inspektoru atributůjsou k dispozici následující vlastnosti:

Snímek obrazovky zobrazuje vlastnosti, které jsou k dispozici v inspektoru atributů.

  • Režim obsahu – umožňuje použít buď zobrazení ( ), nebo buňky ( NSCell ) k zobrazení dat v řádcích a sloupcích. Od macOS 10,7 byste měli použít zobrazení.
  • Nastaví Řádky skupiny – Pokud je v zobrazení tabulka nakreslené buňky seskupené, jako kdyby byly plovoucí.
  • Sloupce – definuje počet zobrazených sloupců.
  • Hlavičky – Pokud budou mít sloupce záhlaví.
  • Změna pořadí – Pokud bude uživatel moci přeuspořádat sloupce v tabulce.
  • Změna velikosti – Pokud bude uživatel moct přetahovat záhlaví sloupců, aby se změnila velikost sloupců.
  • Změna velikosti sloupce – určuje, jak bude tabulka automaticky měnit velikost sloupců.
  • Zvýraznění – určuje typ zvýraznění tabulky používané při výběru buňky.
  • Alternativní řádky – Pokud má jiný řádek jinou barvu pozadí.
  • Vodorovná mřížka – vybere typ ohraničení vykresleného mezi buňkami vodorovně.
  • Svislá mřížka – vybere typ ohraničení vykresleného mezi buňkami svisle.
  • Grid Color – nastaví barvu ohraničení buňky.
  • Background – nastaví barvu pozadí buňky.
  • Výběr – umožňuje řídit, jak může uživatel vybrat buňky v tabulce jako:
    • Více , pokud uživatel může vybrat více řádků a sloupců.
    • Sloupec – Pokud uživatel může vybrat sloupce.
    • Typ Select – Pokud uživatel může zadat znak pro výběr řádku.
    • Prázdné – Pokud uživatel nepožaduje, aby vybral řádek nebo sloupec, neumožňuje v tabulce žádný výběr.
  • Automatické ukládání – název, ve kterém se formát tabulek ukládá, se automaticky uloží.
  • Informace o sloupci – Pokud se bude automaticky ukládat pořadí a šířka sloupců.
  • Konce řádků – vyberte způsob, jakým buňka zpracovává zalomení řádků.
  • Zkrátí poslední viditelné řádky – Pokud by se buňka zkrátila v datech, která se nevejdou do hranic.

Důležité

Pokud neuchováváte starší verzi aplikace Xamarin. Mac, NSView měli byste použít zobrazení tabulek založenou na tabulkách NSCell . NSCell se považuje za starší verzi a nemusí být podporovaná, až dál.

Vyberte sloupec tabulky v hierarchii rozhraní a v inspektoru atributůjsou k dispozici následující vlastnosti:

Snímek obrazovky zobrazuje vlastnosti, které jsou k dispozici pro sloupec tabulky v inspektoru atributů.

  • Title – nastaví název sloupce.
  • Zarovnání – nastaví zarovnání textu v buňkách.
  • Písmo názvu – vybere písmo pro text záhlaví buňky.
  • Klíč řazení – je klíč používaný k řazení dat ve sloupci. Pokud uživatel nemůže tento sloupec seřadit, ponechte prázdné.
  • Selektor – jedná se o akci , která se používá k provedení řazení. Pokud uživatel nemůže tento sloupec seřadit, ponechte prázdné.
  • Order – je pořadím řazení pro data sloupců.
  • Změna velikosti – vybere typ změny velikosti sloupce.
  • Upravitelné – Pokud může uživatel upravovat buňky v tabulce založené na buňkách.
  • Skryté – Pokud je sloupec skrytý.

Velikost sloupce můžete změnit také tak, že přetáhnete jeho úchyt (svisle na pravé straně na pravé straně sloupce) vlevo nebo vpravo.

Pojďme vybrat každý sloupec v našem zobrazení tabulky a zadat název prvního sloupce a druhý Details .

Vyberte v hierarchii rozhraní zobrazení buňky tabulky ( NSTableViewCell ) NSTableViewCell a v inspektoru atributůjsou k dispozici následující vlastnosti:

Snímek obrazovky zobrazuje vlastnosti dostupné pro zobrazení buňky tabulky v inspektoru atributů.

Jedná se o všechny vlastnosti standardního zobrazení. V tomto sloupci máte také možnost změnit velikost řádků.

Vyberte buňku zobrazení tabulky (ve výchozím nastavení to je NSTextField ) v NSTextField a v inspektoru atributůjsou k dispozici následující vlastnosti:

Snímek obrazovky zobrazuje vlastnosti dostupné pro buňku zobrazení tabulky v inspektoru atributů.

Tady budete mít všechny vlastnosti standardního textového pole, které se má nastavit. Ve výchozím nastavení se standardní textové pole používá k zobrazení dat pro buňku ve sloupci.

Vyberte v hierarchii rozhraní zobrazení buňky tabulky ( NSTableFieldCell ) NSTableFieldCell a v inspektoru atributůjsou k dispozici následující vlastnosti:

Snímek obrazovky zobrazuje vlastnosti, které jsou k dispozici pro jinou buňku zobrazení tabulky v inspektoru atributů.

Nejdůležitější nastavení najdete tady:

  • Rozložení – vyberte, jak mají být buňky v tomto sloupci rozloženy.
  • Používá režim single line – Pokud je buňka omezená na jeden řádek.
  • První šířka rozložení modulu runtime – Pokud je při prvním spuštění aplikace buňka preferovat nastavenou šířku (buď ručně, nebo automaticky).
  • Action -Controls při odeslání Akce Edit pro buňku
  • Chování – definuje, jestli je buňka vybraná nebo upravitelná.
  • Formátovaný text – Pokud se v buňce může zobrazit formátovaný text a styl textu.
  • Vrátit zpět – Pokud buňka předpokládá, že je zodpovědností jeho vrácení zpět.

V NSTableFieldCell dolní části sloupce tabulky v NSTableFieldCellvyberte zobrazení buňky tabulky ():

Výběr zobrazení buňky tabulky

To umožňuje upravit zobrazení buňky tabulky používané jako základní vzor pro všechny buňky vytvořené pro daný sloupec.

Přidávání akcí a odbytišť

Stejně jako jakýkoli jiný ovládací prvek pro kakao je potřeba zveřejnit zobrazení tabulky a sloupce a buňky pro kód C# pomocí akcí a odbytišť (na základě požadovaných funkcí).

Tento proces je stejný pro libovolný element tabulkového zobrazení, který chceme zveřejnit:

  1. Přepněte do editoru pomocníka a ujistěte se, že je vybraný soubor:

    Editor pomocníka

  2. Vyberte zobrazení tabulky z hierarchie rozhraní, ovládací prvek a přetáhněte jej na soubor.

  3. Vytvořte výstup pro zobrazení tabulky s názvem :

    Snímek obrazovky ukazuje připojení k zásuvce vytvořené pro zobrazení tabulky s názvem Produktová tabulka.

  4. Vytvořte pro sloupce tabulky také možnosti pro vyvolání a DetailsColumn :

    Snímek obrazovky ukazuje připojení vytvořené pro další tabulková zobrazení.

  5. uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.

V dalším kroku psaní kódu zobrazí data pro tabulku, když je aplikace spuštěná.

Naplnění tabulkového zobrazení

Když je naše zobrazení tabulky navržené v Interface Builder a zveřejněné prostřednictvím zásuvky, pak je potřeba vytvořit kód C# k naplnění.

Nejprve vytvoříme novou Product třídu, která bude uchovávat informace pro jednotlivé řádky. v Průzkumník řešeníklikněte pravým tlačítkem myši na Project a vyberte přidatnový soubor... Vyberte Obecnáprázdná třída, zadejte název a klikněte na tlačítko Nový :

Vytvoření prázdné třídy

Nastavte Product.cs soubor jako následující:

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

Dále je potřeba vytvořit podtřídu NSTableDataSource k poskytnutí dat pro naši tabulku, jak je požadováno. v Průzkumník řešeníklikněte pravým tlačítkem myši na Project a vyberte přidatnový soubor... Vyberte Obecnáprázdná třída, zadejte název a klikněte na tlačítko Nový .

Upravte ProductTableDataSource.cs soubor a nastavte jeho vzhled jako na následující:

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

Tato třída má úložiště pro položky zobrazení tabulky a Přepisuje, GetRowCount aby vracela počet řádků v tabulce.

Nakonec musíme vytvořit podtřídu NSTableDelegate pro zajištění chování naší tabulky. v Průzkumník řešeníklikněte pravým tlačítkem myši na Project a vyberte přidatnový soubor... Vyberte Obecnáprázdná třída, zadejte název a klikněte na tlačítko Nový .

Upravte ProductTableDelegate.cs soubor a nastavte jeho vzhled jako na následující:

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

Když vytvoříme instanci ProductTableDelegate , předáte také instanci ProductTableDataSource , která poskytuje data pro tabulku. GetViewForItemMetoda zodpovídá za vrácení zobrazení (dat) k zobrazení buňky pro sloupec a řádek. Pokud je to možné, pro zobrazení buňky se znovu použije existující zobrazení, pokud není nutné vytvořit nové zobrazení.

Chcete-li naplnit tabulku, upravte ViewController.cs soubor a udělejte AwakeFromNib metodu jako v následujícím:

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

Při spuštění aplikace se zobrazí následující:

Snímek obrazovky se zobrazí okno s názvem tabulka produktů se třemi položkami.

Řazení podle sloupce

Umožní uživateli, aby data v tabulce seřadili kliknutím na záhlaví sloupce. Nejprve dvakrát klikněte na Main.storyboard soubor a otevřete ho pro úpravy v Interface Builder. Vyberte Product sloupec, Title pro selektoru zadejte Productcompare: a vyberte TitleAscendingcompare::

Snímek obrazovky se zobrazí Interface Builder, kde můžete nastavit klíč řazení pro sloupec produkt.

Vyberte Details sloupec, Description pro selektoru zadejte Detailscompare: a vyberte DescriptionAscendingcompare::

Snímek obrazovky ukazuje Interface Builder, kde můžete nastavit klíč řazení pro sloupec details.

uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.

Teď ProductTableDataSource.cs soubor upravte a přidejte následující metody:

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

SortMetoda nám umožňuje seřazení dat ve zdroji dat na základě daného Product pole třídy ve vzestupném nebo sestupném pořadí. Přepsaná SortDescriptorsChanged Metoda bude volána pokaždé, když použijete záhlaví sloupce po kliknutí. Bude předána hodnota klíče , kterou nastavíme v Interface Builder a pořadí řazení pro tento sloupec.

Pokud aplikaci spustíme a kliknete na záhlaví sloupců, řádky se seřadí podle tohoto sloupce:

Příklad spuštění aplikace

Výběr řádku

Pokud chcete, aby uživatel mohl vybrat jeden řádek, otevřete ho dvojitým kliknutím na Main.storyboard soubor pro úpravy v Interface Builder. Vyberte zobrazení tabulky v hierarchii rozhraní a zrušte zaškrtnutí políčka vícenásobná v inspektoru atributů:

Snímek obrazovky ukazuje Interface Builder, kde můžete vybrat více v inspektoru atributů.

uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.

Dále upravte ProductTableDelegate.cs soubor a přidejte následující metodu:

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

Tím umožníte uživateli vybrat kterýkoli jeden řádek v zobrazení tabulky. Vrátí false se pro ShouldSelectRow libovolný řádek, který nechcete, aby uživatel mohl vybrat nebo false pro každý řádek, pokud nechcete, aby uživatel mohl vybrat žádné řádky.

Zobrazení tabulky ( NSTableView ) obsahuje následující metody pro práci s výběrem řádku:

  • DeselectRow(nint) -Odznačte daný řádek v tabulce.
  • SelectRow(nint,bool) – Vybere daný řádek. Předejte false druhému parametru, aby bylo možné vybrat pouze jeden řádek v jednom okamžiku.
  • SelectedRow -Vrátí aktuální řádek vybraný v tabulce.
  • IsRowSelected(nint) – Vrátí true , pokud je vybrán daný řádek.

Vícenásobný výběr řádku

Pokud chcete uživateli dovolit vybrat více řádků, poklikejte na Main.storyboard něj a otevřete ho pro úpravy v Interface Builder. Vyberte zobrazení tabulky v hierarchii rozhraní a zaškrtněte políčko vícenásobné v inspektoru atributů:

Snímek obrazovky zobrazuje Interface Builder, kde můžete vybrat vícenásobné, aby se povolil vícenásobný výběr řádků.

uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.

Dále upravte ProductTableDelegate.cs soubor a přidejte následující metodu:

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

Tím umožníte uživateli vybrat kterýkoli jeden řádek v zobrazení tabulky. Vrátí false se pro ShouldSelectRow libovolný řádek, který nechcete, aby uživatel mohl vybrat nebo false pro každý řádek, pokud nechcete, aby uživatel mohl vybrat žádné řádky.

Zobrazení tabulky ( NSTableView ) obsahuje následující metody pro práci s výběrem řádku:

  • DeselectAll(NSObject) – Vybere možnost zrušit výběr všech řádků v tabulce. Slouží jako this první parametr pro odeslání v objektu, který provádí výběr.
  • DeselectRow(nint) -Odznačte daný řádek v tabulce.
  • SelectAll(NSobject) – Vybere všechny řádky v tabulce. Slouží jako this první parametr pro odeslání v objektu, který provádí výběr.
  • SelectRow(nint,bool) – Vybere daný řádek. Předejte false druhému parametru vymažte výběr a vyberte jenom jeden řádek, předejte true ho k širšímu výběru a zahrňte do něj tento řádek.
  • SelectRows(NSIndexSet,bool) – Vybere danou sadu řádků. Předat false druhému parametru vymažte výběr a vyberte pouze tyto řádky, předejte true Výběr a přidejte tyto řádky.
  • SelectedRow -Vrátí aktuální řádek vybraný v tabulce.
  • SelectedRows -Vrátí a NSIndexSet obsahující indexy vybraných řádků.
  • SelectedRowCount – Vrátí počet vybraných řádků.
  • IsRowSelected(nint) – Vrátí true , pokud je vybrán daný řádek.

Typ pro výběr řádku

Pokud chcete uživateli dovolit zadat znak s vybraným tabulkovým zobrazením a vybrat první řádek s tímto znakem, poklikejte na něj Main.storyboard a otevřete ho pro úpravy v Interface Builder. Vyberte zobrazení tabulky v hierarchii rozhraní a zaškrtněte políčko typ vybrat v inspektoru atributů:

Nastavení typu výběru

uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.

Teď ProductTableDelegate.cs soubor upravte a přidejte následující metodu:

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

GetNextTypeSelectMatchMetoda přebírá daný searchString řádek a vrátí řádek prvního Product , který má daný řetězec v tomto řetězci Title .

Pokud aplikaci spustíme a zadáte znak, vybere se řádek:

Snímek obrazovky ukazuje výsledek spuštění aplikace.

Změna pořadí sloupců

Pokud chcete, aby uživatel mohl přetahovat sloupce v zobrazení tabulky, poklikejte na Main.storyboard soubor a otevřete ho pro úpravy v Interface Builder. Vyberte zobrazení tabulky v hierarchii rozhraní a zaškrtněte políčko změnit pořadí v inspektoru atributů:

Snímek obrazovky ukazuje Interface Builder, kde můžete vybrat Reodering v inspektoru atributů.

Pokud přidáváme hodnotu pro vlastnost resaved a v poliinformace o sloupci , všechny změny, které provedeme v rozložení tabulky, se automaticky uloží pro nás a obnoví se při příštím spuštění aplikace.

uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.

Teď ProductTableDelegate.cs soubor upravte a přidejte následující metodu:

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

ShouldReorderMetoda by měla vracet true pro libovolný sloupec, který má být povolen přeřadit do newColumnIndex , jinak vrátit false ;

Pokud aplikaci spustíme, můžeme přetáhnout záhlaví sloupců pro změnu pořadí sloupců:

Příklad přeuspořádaných sloupců

Úprava buněk

Pokud chcete uživateli povolit úpravy hodnot pro danou buňku, upravte soubor a ProductTableDelegate.cs změňte GetViewForItem metodu následujícím způsobem:

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

Když teď spustíme aplikaci, může uživatel upravit buňky v zobrazení tabulky:

Příklad úpravy buňky

Použití obrázků v zobrazení tabulek

Pokud chcete zahrnout obrázek jako součást buňky v , budete muset změnit způsob, jakým metoda zobrazení tabulky vrací data, aby místo typického používá NSTableViewNSTableViewDelegate'sGetViewForItemNSTableCellViewNSTextField . Například:

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

Další informace najdete v části Použití obrázků se zobrazeními tabulky v naší dokumentaci Práce s obrázkem.

Přidání tlačítka Odstranit do řádku

V závislosti na požadavcích vaší aplikace můžou být situace, kdy budete muset pro každý řádek v tabulce zadat tlačítko akce. Jako příklad tohoto příkladu rozbalme výše vytvořený příklad zobrazení tabulky, aby na každý řádek zahrnul tlačítko Odstranit.

Nejprve upravte v souboru Xcode Interface Builder zobrazení tabulky a zvyšte počet sloupců Main.storyboard na tři (3). Dále změňte Název nového sloupce na :

Úprava názvu sloupce

Uložte změny scénáře a vraťte se do Visual Studio pro Mac a tyto změny synchronizujte.

Dále upravte soubor ViewController.cs a přidejte následující veřejnou metodu:

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

Ve stejném souboru upravte vytvoření nového delegáta zobrazení tabulky uvnitř metody ViewDidLoad následujícím způsobem:

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

Teď upravte soubor tak, aby zahrnoval privátní připojení ke kontroleru zobrazení, a při vytváření nové instance delegáta převezměte kontroler jako ProductTableDelegate.cs parametr:

#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

Dále přidejte do třídy následující novou soukromou metodu:

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

To vezme všechny konfigurace zobrazení textu, které se dříve provedly v metodě , a umístí je do jednoho volatelného umístění (protože poslední sloupec tabulky neobsahuje zobrazení textu, ale GetViewForItem tlačítko).

Nakonec upravte GetViewForItem metodu a vytvořte, aby vypadala takto:

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

Podívejme se na několik částí tohoto kódu podrobněji. Nejprve se na základě názvu sloupce vytvoří nová NSTableViewCell akce. Pro první dva sloupce (Product a Details) se volá nová metoda.

Ve sloupci Akce se vytvoří nový objekt a přidá se do buňky jako dílčí zobrazení:

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

Vlastnost Button slouží k podržení čísla aktuálně Tag zpracovávaných řádků. Toto číslo se použije později, když uživatel požádá o odstranění řádku v události Activated tlačítka:

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

Na začátku obslužné rutiny události se zobrazí tlačítko a produkt, který je na daném řádku tabulky. Pak se uživateli zobrazí upozornění potvrzující odstranění řádku. Pokud se uživatel rozhodne řádek odstranit, daný řádek se odebere ze zdroje dat a tabulka se znovu načte:

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

Pokud se buňka zobrazení tabulky znovu používá místo vytváření nové buňky, následující kód ji nakonfiguruje na základě zpracovávaných sloupců:

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

U sloupce Akce se všechna dílčí zobrazení prohledá, dokud se nenašetří a vlastnost se aktualizuje tak, aby odkazovala na aktuální Tag řádek.

Po provedení těchto změn bude mít při spuštění aplikace na každém řádku tlačítko Odstranit:

Zobrazení tabulky s tlačítky odstranění

Když uživatel klikne na tlačítko Odstranit, zobrazí se upozornění s žádostí o odstranění daného řádku:

Upozornění na odstranění řádku

Pokud uživatel zvolí odstranění, řádek se odebere a tabulka se znovu vykreslí:

Tabulka po odstranění řádku

Zobrazení tabulky datových vazeb

Použitím technik Key-Value kódování a datových vazeb v aplikaci Xamarin.Mac můžete výrazně snížit množství kódu, který musíte napsat a udržovat, abyste mohli naplnit prvky uživatelského rozhraní a pracovat s těmito prvky. Výhodou je také další oddělení zálohovací dat (datovýmodel)od front-endového Uživatelské rozhraní (model-zobrazení-kontroler),což usnadňuje údržbu a flexibilnější návrh aplikací.

Key-Value Code (KVC) je mechanismus pro nepřímou přístup k vlastnostem objektu pomocí klíčů (speciálně formátovaných řetězců) k identifikaci vlastností místo přístupu k nim prostřednictvím proměnných instance nebo metod přistupující metody ( get/set ). Implementací přistupovacích Key-Value, které jsou kompatibilní s kódováním Key-Value, v aplikaci Xamarin.Mac získáte přístup k dalším funkcím macOS, jako jsou Key-Value Observing (KVO), datové vazby, základní data, vazby Cocoa a skriptovatelnost.

Další informace najdete v části Datová vazba zobrazení tabulky naší dokumentace k datovým vazbách a Key-Value kódování.

Souhrn

Tento článek podrobně popisuje práci se zobrazeními tabulek v aplikaci Xamarin.Mac. Viděli jsme různé typy a použití zobrazení tabulek, jak vytvářet a udržovat zobrazení tabulek v jazyce Xcode Interface Builder jak pracovat se zobrazeními tabulek v kódu jazyka C#.