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.
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:
Tím se otevře návrh okna Interface Builder Xcode:
Zadejte table do vyhledávacího pole v table , aby bylo snazší najít ovládací prvky zobrazení tabulky:
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í:
Vyberte zobrazení tabulky v hierarchii rozhraní a v inspektoru atributůjsou k dispozici následující vlastnosti:
- 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:
- 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:
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:
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:
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 ():
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:
Přepněte do editoru pomocníka a ujistěte se, že je vybraný soubor:
Vyberte zobrazení tabulky z hierarchie rozhraní, ovládací prvek a přetáhněte jej na soubor.
Vytvořte výstup pro zobrazení tabulky s názvem :
Vytvořte pro sloupce tabulky také možnosti pro vyvolání a
DetailsColumn: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ý :
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í:
Ř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::
Vyberte Details sloupec, Description pro selektoru zadejte Detailscompare: a vyberte DescriptionAscendingcompare::
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:
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ů:
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ředejtefalsedruhé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ů:
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ží jakothisprvní 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ží jakothisprvní parametr pro odeslání v objektu, který provádí výběr.SelectRow(nint,bool)– Vybere daný řádek. Předejtefalsedruhému parametru vymažte výběr a vyberte jenom jeden řádek, předejtetrueho k širšímu výběru a zahrňte do něj tento řádek.SelectRows(NSIndexSet,bool)– Vybere danou sadu řádků. Předatfalsedruhému parametru vymažte výběr a vyberte pouze tyto řádky, předejtetrueVýběr a přidejte tyto řádky.SelectedRow-Vrátí aktuální řádek vybraný v tabulce.SelectedRows-Vrátí aNSIndexSetobsahují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ů:
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:
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ů:
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ů:
Ú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:
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 :
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:
Když uživatel klikne na tlačítko Odstranit, zobrazí se upozornění s žádostí o odstranění daného řádku:
Pokud uživatel zvolí odstranění, řádek se odebere a tabulka se znovu vykreslí:
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#.





























