Kódování datových vazeb a klíč-hodnota v Xamarin.Mac
Tento článek popisuje použití kódování klíč-hodnota a klíč-hodnota pozorování, aby bylo možné datovou vazbu s prvky uživatelského rozhraní v Xcode Interface Builder.
Přehled
Při práci s C# a .NET v aplikaci Xamarin.Mac máte přístup ke stejným technikám kódování klíč-hodnota a datové vazby, které vývojář pracuje v Objective-C Xcode. Vzhledem k tomu, že se Xamarin.Mac integruje přímo s Xcode, můžete místo psaní kódu použít Tvůrce rozhraní Xcode k vytvoření vazby dat s prvky uživatelského rozhraní.
Pomocí technik kódování klíč-hodnota a datových vazeb v aplikaci Xamarin.Mac můžete výrazně snížit množství kódu, který musíte psát a udržovat pro naplnění a práci s prvky uživatelského rozhraní. Výhodou je také další oddělení backingových dat (datový model) od front-endového uživatelského rozhraní (Model-View-Controller), což usnadňuje údržbu a flexibilnější návrh aplikace.
V tomto článku se budeme zabývat základy práce s kódováním klíč-hodnota a datovými vazbami v aplikaci Xamarin.Mac. Důrazně doporučujeme, abyste si nejprve prošli článek Hello, Mac , konkrétně úvod do Xcode a Tvůrce rozhraní a výstupy a akce , protože se zabývá klíčovými koncepty a technikami, které budeme používat v tomto článku.
Možná se budete chtít podívat také na třídy a metody v jazyce C#, které jsou uvedeny v Objective-C dokumentu Xamarin.Mac Internals , vysvětluje Register
Export
a atributy používané k připojení tříd jazyka C# k Objective-C objektům a prvkům uživatelského rozhraní.
Co je kódování klíč-hodnota
Kódování klíč-hodnota (KVC) je mechanismus pro přístup k vlastnostem objektu nepřímo pomocí klíčů (speciálně formátovaných řetězců) k identifikaci vlastností místo přístupu prostřednictvím proměnných instancí nebo metod přístupových objektů (get/set
). Implementací přístupových objektů kompatibilních s klíč-hodnota v aplikaci Xamarin.Mac získáte přístup k dalším funkcím systému macOS (dříve označovaným jako OS X), jako je sledování klíč-hodnota (KVO), datová vazba, základní data, vazby Cocoa a skriptovatelnost.
Pomocí technik kódování klíč-hodnota a datových vazeb v aplikaci Xamarin.Mac můžete výrazně snížit množství kódu, který musíte psát a udržovat pro naplnění a práci s prvky uživatelského rozhraní. Výhodou je také další oddělení backingových dat (datový model) od front-endového uživatelského rozhraní (Model-View-Controller), což usnadňuje údržbu a flexibilnější návrh aplikace.
Podívejme se například na následující definici třídy objektu kompatibilního s KVC:
using System;
using Foundation;
namespace MacDatabinding
{
[Register("PersonModel")]
public class PersonModel : NSObject
{
private string _name = "";
[Export("Name")]
public string Name {
get { return _name; }
set {
WillChangeValue ("Name");
_name = value;
DidChangeValue ("Name");
}
}
public PersonModel ()
{
}
}
}
[Register("PersonModel")]
Nejprve atribut zaregistruje třídu a zpřístupní ji Objective-C. Pak třída musí dědit z NSObject
(nebo podtřídy, která dědí z NSObject
), tím se přidá několik základních metod, které umožňují třídě být kompatibilní s KVC. [Export("Name")]
Dále atribut zpřístupňuje Name
vlastnost a definuje hodnotu klíče, která se později použije pro přístup k vlastnosti prostřednictvím technik KVC a KVO.
Aby bylo možné být schopni být pozorované změny hodnoty klíč-hodnota u hodnoty vlastnosti, musí přístupové objekty zabalit změny jeho hodnoty do WillChangeValue
volání metody a DidChangeValue
volání metody (určení stejného klíče jako Export
atribut). Příklad:
set {
WillChangeValue ("Name");
_name = value;
DidChangeValue ("Name");
}
Tento krok je velmi důležitý pro datovou vazbu v Tvůrci rozhraní Xcode (jak uvidíme dále v tomto článku).
Další informace najdete v Průvodci programováním pro kódování klíč-hodnota společnosti Apple.
Klíče a cesty ke klíčům
Klíč je řetězec, který identifikuje konkrétní vlastnost objektu. Klíč obvykle odpovídá názvu metody přístupového objektu v objektu kompatibilním s klíč-hodnota. Klíče musí používat kódování ASCII, obvykle začínají malým písmenem a nemusí obsahovat prázdné znaky. Vzhledem k výše uvedenému Name
příkladu by byla hodnota Name
klíče vlastnosti PersonModel
třídy. Klíč a název vlastnosti, kterou zpřístupňují, nemusí být stejné, ale ve většině případů jsou.
Cesta ke klíči je řetězec tečkovaných klíčů, který slouží k určení hierarchie vlastností objektu, které se mají procházet. Vlastnost prvního klíče v sekvenci je relativní vůči příjemci a každý další klíč se vyhodnotí vzhledem k hodnotě předchozí vlastnosti. Stejným způsobem použijete tečku k procházení objektu a jeho vlastností ve třídě jazyka C#.
Pokud jste například rozšířili PersonModel
třídu a přidali Child
vlastnost:
using System;
using Foundation;
namespace MacDatabinding
{
[Register("PersonModel")]
public class PersonModel : NSObject
{
private string _name = "";
private PersonModel _child = new PersonModel();
[Export("Name")]
public string Name {
get { return _name; }
set {
WillChangeValue ("Name");
_name = value;
DidChangeValue ("Name");
}
}
[Export("Child")]
public PersonModel Child {
get { return _child; }
set {
WillChangeValue ("Child");
_child = value;
DidChangeValue ("Child");
}
}
public PersonModel ()
{
}
}
}
Cesta ke klíči k názvu dítěte by byla self.Child.Name
nebo jednoduše Child.Name
(na základě způsobu použití hodnoty klíče).
Získání hodnot pomocí kódování klíč-hodnota
Metoda ValueForKey
vrátí hodnotu pro zadaný klíč (jako a NSString
), vzhledem k instanci třídy KVC přijímající požadavek. Pokud je například Person
instance PersonModel
třídy definované výše:
// Read value
var name = Person.ValueForKey (new NSString("Name"));
Tato hodnota by vrátila Name
hodnotu vlastnosti pro danou PersonModel
instanci .
Nastavení hodnot pomocí kódování klíč-hodnota
SetValueForKey
Podobně nastaví hodnotu pro zadaný klíč (jako aNSString
), vzhledem k instanci třídy KVC, která přijímá požadavek. Znovu použijte instanci PersonModel
třídy, jak je znázorněno níže:
// Write value
Person.SetValueForKey(new NSString("Jane Doe"), new NSString("Name"));
Hodnota vlastnosti by se změnila Name
na Jane Doe
.
Sledování změn hodnot
Pomocí pozorování klíčové hodnoty (KVO) můžete pozorovatele připojit ke konkrétnímu klíči třídy kompatibilní s KVC a být upozorněni kdykoliv, když se změní hodnota tohoto klíče (buď pomocí technik KVC, nebo přímý přístup k dané vlastnosti v kódu jazyka C#). Příklad:
// Watch for the name value changing
Person.AddObserver ("Name", NSKeyValueObservingOptions.New, (sender) => {
// Inform caller of selection change
Console.WriteLine("New Name: {0}", Person.Name)
});
Nyní, kdykoli Name
vlastnost Person
instance PersonModel
třídy je změněna, nová hodnota je zapsána do konzoly.
Další informace najdete v příručce Apple Introduction to Key-Value Observing Programming Guide.
Datová vazba
V následujících částech se dozvíte, jak můžete pomocí kódování klíč-hodnota a hodnoty klíč-hodnota sledovat vyhovující třídu pro vazbu dat k prvkům uživatelského rozhraní v Tvůrci rozhraní Xcode místo čtení a zápisu hodnot pomocí kódu jazyka C#. Tímto způsobem oddělíte datový model od zobrazení, která se používají k jejich zobrazení, aby byla aplikace Xamarin.Mac flexibilnější a jednodušší. Výrazně také snížíte množství kódu, který se musí napsat.
Definování datového modelu
Než budete moct vytvořit vazbu prvku uživatelského rozhraní v Tvůrci rozhraní, musíte mít v aplikaci Xamarin.Mac definovanou třídu kompatibilní s KVC/KVO, aby fungovala jako datový model pro vazbu. Datový model poskytuje všechna data, která se zobrazí v uživatelském rozhraní, a přijímá veškeré úpravy dat, která uživatel provede v uživatelském rozhraní při spuštění aplikace.
Pokud například píšete aplikaci, která spravuje skupinu zaměstnanců, můžete k definování datového modelu použít následující třídu:
using System;
using Foundation;
using AppKit;
namespace MacDatabinding
{
[Register("PersonModel")]
public class PersonModel : NSObject
{
#region Private Variables
private string _name = "";
private string _occupation = "";
private bool _isManager = false;
private NSMutableArray _people = new NSMutableArray();
#endregion
#region Computed Properties
[Export("Name")]
public string Name {
get { return _name; }
set {
WillChangeValue ("Name");
_name = value;
DidChangeValue ("Name");
}
}
[Export("Occupation")]
public string Occupation {
get { return _occupation; }
set {
WillChangeValue ("Occupation");
_occupation = value;
DidChangeValue ("Occupation");
}
}
[Export("isManager")]
public bool isManager {
get { return _isManager; }
set {
WillChangeValue ("isManager");
WillChangeValue ("Icon");
_isManager = value;
DidChangeValue ("isManager");
DidChangeValue ("Icon");
}
}
[Export("isEmployee")]
public bool isEmployee {
get { return (NumberOfEmployees == 0); }
}
[Export("Icon")]
public NSImage Icon {
get {
if (isManager) {
return NSImage.ImageNamed ("group.png");
} else {
return NSImage.ImageNamed ("user.png");
}
}
}
[Export("personModelArray")]
public NSArray People {
get { return _people; }
}
[Export("NumberOfEmployees")]
public nint NumberOfEmployees {
get { return (nint)_people.Count; }
}
#endregion
#region Constructors
public PersonModel ()
{
}
public PersonModel (string name, string occupation)
{
// Initialize
this.Name = name;
this.Occupation = occupation;
}
public PersonModel (string name, string occupation, bool manager)
{
// Initialize
this.Name = name;
this.Occupation = occupation;
this.isManager = manager;
}
#endregion
#region Array Controller Methods
[Export("addObject:")]
public void AddPerson(PersonModel person) {
WillChangeValue ("personModelArray");
isManager = true;
_people.Add (person);
DidChangeValue ("personModelArray");
}
[Export("insertObject:inPersonModelArrayAtIndex:")]
public void InsertPerson(PersonModel person, nint index) {
WillChangeValue ("personModelArray");
_people.Insert (person, index);
DidChangeValue ("personModelArray");
}
[Export("removeObjectFromPersonModelArrayAtIndex:")]
public void RemovePerson(nint index) {
WillChangeValue ("personModelArray");
_people.RemoveObject (index);
DidChangeValue ("personModelArray");
}
[Export("setPersonModelArray:")]
public void SetPeople(NSMutableArray array) {
WillChangeValue ("personModelArray");
_people = array;
DidChangeValue ("personModelArray");
}
#endregion
}
}
Většina funkcí této třídy byla popsána v části Co je kódování klíč-hodnota výše. Pojďme se ale podívat na několik konkrétních prvků a několik dalších prvků, které byly provedeny, aby tato třída fungovala jako datový model pro kontrolery polí a kontrolery stromu (které budeme později používat k vytvoření vazby stromových zobrazení, zobrazení osnovy a zobrazení kolekce).
Za prvé, protože zaměstnanec může být manažerem, použili NSArray
jsme (konkrétně tak, NSMutableArray
aby se hodnoty daly upravit), abychom zaměstnancům umožnili jejich připojení:
private NSMutableArray _people = new NSMutableArray();
...
[Export("personModelArray")]
public NSArray People {
get { return _people; }
}
Tady si poznamenejte dvě věci:
- Místo standardního pole nebo kolekce jazyka C# jsme použili
NSMutableArray
, protože se jedná o požadavek na vytvoření vazby dat s ovládacími prvky AppKitu, jako jsou zobrazení tabulek, zobrazení osnovy a kolekce. - Pole zaměstnanců jsme odhalili tak, že ho přetypujeme pro
NSArray
účely datových vazeb a změníme jeho formátovaný název jazyka C#,People
na ten, který datová vazba očekává, ve tvaru {class_name}Matice (všimněte si,personModelArray
že první znak byl proveden v malých písmenech).
Dále musíme přidat některé speciálně pojmenování veřejných metod pro podporu řadičů polí a řadičů stromové struktury:
[Export("addObject:")]
public void AddPerson(PersonModel person) {
WillChangeValue ("personModelArray");
isManager = true;
_people.Add (person);
DidChangeValue ("personModelArray");
}
[Export("insertObject:inPersonModelArrayAtIndex:")]
public void InsertPerson(PersonModel person, nint index) {
WillChangeValue ("personModelArray");
_people.Insert (person, index);
DidChangeValue ("personModelArray");
}
[Export("removeObjectFromPersonModelArrayAtIndex:")]
public void RemovePerson(nint index) {
WillChangeValue ("personModelArray");
_people.RemoveObject (index);
DidChangeValue ("personModelArray");
}
[Export("setPersonModelArray:")]
public void SetPeople(NSMutableArray array) {
WillChangeValue ("personModelArray");
_people = array;
DidChangeValue ("personModelArray");
}
Ty umožňují řadičům požadovat a upravit data, která zobrazují. Stejně jako výše uvedené NSArray
mají tyto zásady vytváření názvů velmi specifické (liší se od obvyklých konvencí vytváření názvů jazyka C#):
addObject:
- Přidá objekt do pole.insertObject:in{class_name}ArrayAtIndex:
- Kde{class_name}
je název předmětu. Tato metoda vloží objekt do pole v daném indexu.removeObjectFrom{class_name}ArrayAtIndex:
- Kde{class_name}
je název předmětu. Tato metoda odebere objekt v poli v daném indexu.set{class_name}Array:
- Kde{class_name}
je název předmětu. Tato metoda umožňuje nahradit existující přenos novým.
Uvnitř těchto metod jsme zabalili změny pole do WillChangeValue
polí a DidChangeValue
zpráv pro dodržování předpisů KVO.
A konečně, protože vlastnost Icon
spoléhá na hodnotu isManager
vlastnosti, isManager
změny vlastnosti nemusí být promítnuty do prvků uživatelského rozhraní vázaného na Icon
data (během KVO):
[Export("Icon")]
public NSImage Icon {
get {
if (isManager) {
return NSImage.ImageNamed ("group.png");
} else {
return NSImage.ImageNamed ("user.png");
}
}
}
Abychom to mohli opravit, použijeme následující kód:
[Export("isManager")]
public bool isManager {
get { return _isManager; }
set {
WillChangeValue ("isManager");
WillChangeValue ("Icon");
_isManager = value;
DidChangeValue ("isManager");
DidChangeValue ("Icon");
}
}
Všimněte si, isManager
že kromě vlastního klíče také příslušenství odesílá WillChangeValue
klíče a DidChangeValue
zprávy, Icon
aby se změny zobrazily také.
Datový model budeme používat PersonModel
v celém zbytku tohoto článku.
Jednoduchá datová vazba
S definovaným datovým modelem se podíváme na jednoduchý příklad datové vazby v Tvůrci rozhraní Xcode. Pojďme například přidat formulář do naší aplikace Xamarin.Mac, kterou můžete použít k úpravě výše definovaného PersonModel
kódu. Přidáme několik textových polí a zaškrtávací políčko pro zobrazení a úpravu vlastností našeho modelu.
Nejprve přidáme nový kontroler zobrazení do souboru Main.storyboard v Tvůrci rozhraní a pojmenujeme jeho třídu SimpleViewController
:
V dalším kroku se vraťte do Visual Studio pro Mac, upravte soubor SimpleViewController.cs (který se automaticky přidal do projektu) a zveřejníme instanciPersonModel
, se kterou budeme s formulářem svázání dat. Přidejte následující kód:
private PersonModel _person = new PersonModel();
...
[Export("Person")]
public PersonModel Person {
get {return _person; }
set {
WillChangeValue ("Person");
_person = value;
DidChangeValue ("Person");
}
}
Při načtení zobrazení vytvoříme instanci našeho PersonModel
kódu a naplníme ho tímto kódem:
public override void ViewDidLoad ()
{
base.AwakeFromNib ();
// Set a default person
var Craig = new PersonModel ("Craig Dunn", "Documentation Manager");
Craig.AddPerson (new PersonModel ("Amy Burns", "Technical Writer"));
Craig.AddPerson (new PersonModel ("Joel Martinez", "Web & Infrastructure"));
Craig.AddPerson (new PersonModel ("Kevin Mullins", "Technical Writer"));
Craig.AddPerson (new PersonModel ("Mark McLemore", "Technical Writer"));
Craig.AddPerson (new PersonModel ("Tom Opgenorth", "Technical Writer"));
Person = Craig;
}
Teď potřebujeme vytvořit formulář, poklikejte na soubor Main.storyboard a otevřete ho pro úpravy v Tvůrci rozhraní. Rozložení formuláře tak, aby vypadalo přibližně takto:
Chcete-li vytvořit vazbu formuláře na PersonModel
formulář, který jsme odhalili prostřednictvím Person
klíče, postupujte takto:
Vyberte textové pole jméno zaměstnance a přepněte na kontrolu vazeb.
Zaškrtněte políčko Vytvořit vazbu a v rozevíracím seznamu vyberte Jednoduchý kontroler zobrazení. Dále zadejte
self.Person.Name
cestu ke klíči:Vyberte textové pole o zaměstnání a zaškrtněte políčko Vytvořit vazbu a v rozevíracím seznamu vyberte Jednoduchý kontroler zobrazení. Dále zadejte
self.Person.Occupation
cestu ke klíči:Zaškrtněte políčko Zaměstnanec je zaškrtávací políčko Správce a zaškrtněte políčko Vytvořit vazbu a v rozevíracím seznamu vyberte Jednoduchý kontroler zobrazení. Dále zadejte
self.Person.isManager
cestu ke klíči:Vyberte pole Počet zaměstnanců spravovaného textu a zaškrtněte políčko Vytvořit vazbu a v rozevíracím seznamu vyberte Jednoduchý kontroler zobrazení. Dále zadejte
self.Person.NumberOfEmployees
cestu ke klíči:Pokud zaměstnanec není manažerem, chceme skrýt pole Počet spravovaných popisků zaměstnanců a textové pole.
Vyberte Popisek Spravovaný počet zaměstnanců, rozbalte skrytý seznam a zaškrtněte políčko Vytvořit vazbu a v rozevíracím seznamu vyberte Jednoduchý kontroler zobrazení. Dále zadejte
self.Person.isManager
cestu ke klíči:V rozevíracím seznamu Value Transformer vyberte
NSNegateBoolean
:To říká datové vazbě, že popisek bude skrytý, pokud je
false
hodnotaisManager
vlastnosti .Opakujte kroky 7 a 8 pro pole Počet zaměstnanců spravovaného textu.
Uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.
Pokud aplikaci spustíte, hodnoty z Person
vlastnosti se automaticky vyplní v našem formuláři:
Všechny změny provedené uživateli ve formuláři se zapíšou zpět do Person
vlastnosti v kontroleru zobrazení. Například zrušení výběru zaměstnance je manažer aktualizuje Person
instanci našeho PersonModel
a počet zaměstnanců spravovaný popisek a textové pole jsou skryté automaticky (prostřednictvím datové vazby):
Datová vazba zobrazení tabulky
Teď, když máme základní informace o datových vazbách mimo cestu, se podíváme na složitější úlohu datové vazby pomocí kontroleru pole a datové vazby na zobrazení tabulky. Další informace o práci se zobrazeními tabulek najdete v naší dokumentaci k zobrazením tabulek.
Nejprve přidáme nový kontroler zobrazení do souboru Main.storyboard v Tvůrci rozhraní a pojmenujeme jeho třídu TableViewController
:
V dalším kroku upravíme soubor TableViewController.cs (který byl automaticky přidán do projektu) a zveřejníme pole (NSArray
) PersonModel
tříd, se kterými budeme datově svázání formuláře. Přidejte následující kód:
private NSMutableArray _people = new NSMutableArray();
...
[Export("personModelArray")]
public NSArray People {
get { return _people; }
}
...
[Export("addObject:")]
public void AddPerson(PersonModel person) {
WillChangeValue ("personModelArray");
_people.Add (person);
DidChangeValue ("personModelArray");
}
[Export("insertObject:inPersonModelArrayAtIndex:")]
public void InsertPerson(PersonModel person, nint index) {
WillChangeValue ("personModelArray");
_people.Insert (person, index);
DidChangeValue ("personModelArray");
}
[Export("removeObjectFromPersonModelArrayAtIndex:")]
public void RemovePerson(nint index) {
WillChangeValue ("personModelArray");
_people.RemoveObject (index);
DidChangeValue ("personModelArray");
}
[Export("setPersonModelArray:")]
public void SetPeople(NSMutableArray array) {
WillChangeValue ("personModelArray");
_people = array;
DidChangeValue ("personModelArray");
}
Stejně jako jsme to udělali PersonModel
ve výše uvedené třídě v části Definování datového modelu , jsme zveřejnili čtyři speciálně pojmenované veřejné metody, aby kontroler pole a četl a zapisoval data z naší kolekce PersonModels
.
Při načtení zobrazení musíme naplnit pole tímto kódem:
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Build list of employees
AddPerson (new PersonModel ("Craig Dunn", "Documentation Manager", true));
AddPerson (new PersonModel ("Amy Burns", "Technical Writer"));
AddPerson (new PersonModel ("Joel Martinez", "Web & Infrastructure"));
AddPerson (new PersonModel ("Kevin Mullins", "Technical Writer"));
AddPerson (new PersonModel ("Mark McLemore", "Technical Writer"));
AddPerson (new PersonModel ("Tom Opgenorth", "Technical Writer"));
AddPerson (new PersonModel ("Larry O'Brien", "API Documentation Manager", true));
AddPerson (new PersonModel ("Mike Norman", "API Documenter"));
}
Teď potřebujeme vytvořit zobrazení tabulky, poklikáním otevřete soubor Main.storyboard pro úpravy v Tvůrci rozhraní. Rozložení tabulky tak, aby vypadalo přibližně takto:
Potřebujeme přidat řadič pole, který poskytuje svázaná data do naší tabulky, postupujte takto:
Přetáhněte řadič pole z inspektoru knihovny do editoru rozhraní:
Vyberte řadič pole v hierarchii rozhraní a přepněte na inspektor atributů:
Zadejte
PersonModel
název třídy, klikněte na tlačítko Plus a přidejte tři klávesy. Pojmenujte jeName
Occupation
aisManager
:Tím kontroleru pole řeknete, o čem spravuje pole a o které vlastnosti by měl být vystaven (prostřednictvím klíčů).
Přepněte na kontrolu vazeb a v části Pole obsahu vyberte Bind to (Vytvořit vazbu) a Table View Controller (Kontroler zobrazení tabulky). Zadejte cestu
self.personModelArray
ke klíči modelu:Tím se prováže maticový kontroler s polem
PersonModels
, které jsme odhalili na kontroleru zobrazení.
Teď potřebujeme svázat zobrazení tabulky s kontrolerem pole, postupujte takto:
Vyberte zobrazení tabulky a kontrolu vazeb:
V rozevíracím seznamu Obsah tabulky vyberte Bind to a Array Controller. Zadejte
arrangedObjects
pro pole Klíč kontroleru:Vyberte buňku zobrazení tabulky pod sloupcem Zaměstnanec. V nástroji Bindings Inspector v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu k buňce a Zobrazení buněk tabulky. Zadejte
objectValue.Name
cestu ke klíči modelu:objectValue
je aktuálníPersonModel
v poli spravovaném kontrolerem pole.Ve sloupci Zaměstnání vyberte buňku zobrazení tabulky. V nástroji Bindings Inspector v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu k buňce a Zobrazení buněk tabulky. Zadejte
objectValue.Occupation
cestu ke klíči modelu:Uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.
Pokud spustíme aplikaci, tabulka se naplní naším polem PersonModels
:
Datová vazba zobrazení osnovy
datová vazba vůči zobrazení osnovy je velmi podobná vazbě vůči zobrazení tabulky. Klíčovým rozdílem je, že místo kontroleru pole použijeme kontroler stromu, abychom poskytli svázaná data do zobrazení osnovy. Další informace o práci se zobrazeními osnovy najdete v naší dokumentaci k zobrazení osnovy .
Nejprve přidáme nový kontroler zobrazení do souboru Main.storyboard v Tvůrci rozhraní a pojmenujeme jeho třídu OutlineViewController
:
V dalším kroku upravíme soubor OutlineViewController.cs (který se automaticky přidal do projektu) a zveřejníme pole (NSArray
) PersonModel
tříd, se kterými budeme datovými vazbami formuláře. Přidejte následující kód:
private NSMutableArray _people = new NSMutableArray();
...
[Export("personModelArray")]
public NSArray People {
get { return _people; }
}
...
[Export("addObject:")]
public void AddPerson(PersonModel person) {
WillChangeValue ("personModelArray");
_people.Add (person);
DidChangeValue ("personModelArray");
}
[Export("insertObject:inPersonModelArrayAtIndex:")]
public void InsertPerson(PersonModel person, nint index) {
WillChangeValue ("personModelArray");
_people.Insert (person, index);
DidChangeValue ("personModelArray");
}
[Export("removeObjectFromPersonModelArrayAtIndex:")]
public void RemovePerson(nint index) {
WillChangeValue ("personModelArray");
_people.RemoveObject (index);
DidChangeValue ("personModelArray");
}
[Export("setPersonModelArray:")]
public void SetPeople(NSMutableArray array) {
WillChangeValue ("personModelArray");
_people = array;
DidChangeValue ("personModelArray");
}
Stejně jako jsme to udělali PersonModel
ve výše uvedené třídě v části Definování datového modelu , jsme zveřejnili čtyři speciálně pojmenované veřejné metody, aby kontroler stromu četl a zapisoval data z naší kolekce PersonModels
.
Při načtení zobrazení musíme naplnit pole tímto kódem:
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Build list of employees
var Craig = new PersonModel ("Craig Dunn", "Documentation Manager");
Craig.AddPerson (new PersonModel ("Amy Burns", "Technical Writer"));
Craig.AddPerson (new PersonModel ("Joel Martinez", "Web & Infrastructure"));
Craig.AddPerson (new PersonModel ("Kevin Mullins", "Technical Writer"));
Craig.AddPerson (new PersonModel ("Mark McLemore", "Technical Writer"));
Craig.AddPerson (new PersonModel ("Tom Opgenorth", "Technical Writer"));
AddPerson (Craig);
var Larry = new PersonModel ("Larry O'Brien", "API Documentation Manager");
Larry.AddPerson (new PersonModel ("Mike Norman", "API Documenter"));
AddPerson (Larry);
}
Teď potřebujeme vytvořit zobrazení osnovy, poklikáním na soubor Main.storyboard ho otevřete pro úpravy v Tvůrci rozhraní. Rozložení tabulky tak, aby vypadalo přibližně takto:
Potřebujeme přidat kontroler stromu, který poskytuje svázaná data do osnovy, postupujte takto:
Přetáhněte kontroler stromu z nástroje Library Inspector do editoru rozhraní:
V hierarchii rozhraní vyberte kontroler stromu a přepněte na kontrolu atributů:
Zadejte
PersonModel
název třídy, klikněte na tlačítko Plus a přidejte tři klávesy. Pojmenujte jeName
Occupation
aisManager
:To říká kontroleru stromové struktury, o čem spravuje pole a o které vlastnosti by měl být vystaven (prostřednictvím klíčů).
V části Řadič stromu zadejte
personModelArray
pro podřízené položky do poleNumberOfEmployees
Počet a zadejte visEmployee
části List:To říká řadiči stromu, kde najít všechny podřízené uzly, kolik podřízených uzlů existuje a jestli má aktuální uzel podřízené uzly.
Přepněte na Kontrolu vazeb a v části Pole obsahu vyberte Vytvořit vazbu a Vlastník souboru. Zadejte cestu
self.personModelArray
ke klíči modelu:Tím se prováže stromový kontroler s polem
PersonModels
, které jsme odhalili na kontroleru zobrazení.
Teď musíme svázat zobrazení osnovy se stromem kontroleru, postupujte takto:
Vyberte zobrazení osnovy a v inspektoru vazeb vyberte:
V rozevíracím seznamu Obsah zobrazení osnovy vyberte Vytvořit vazbu a kontroler stromu. Zadejte
arrangedObjects
pro pole Klíč kontroleru:Vyberte buňku zobrazení tabulky pod sloupcem Zaměstnanec. V nástroji Bindings Inspector v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu k buňce a Zobrazení buněk tabulky. Zadejte
objectValue.Name
cestu ke klíči modelu:objectValue
je aktuálníPersonModel
v poli spravovaném kontrolerem stromové struktury.Ve sloupci Zaměstnání vyberte buňku zobrazení tabulky. V nástroji Bindings Inspector v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu k buňce a Zobrazení buněk tabulky. Zadejte
objectValue.Occupation
cestu ke klíči modelu:Uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.
Pokud spustíme aplikaci, osnova se naplní naším polem PersonModels
:
Datová vazba zobrazení kolekce
Datová vazba se zobrazením kolekce je velmi podobná vazbě se zobrazením tabulky, protože řadič pole slouží k poskytování dat pro kolekci. Vzhledem k tomu, že zobrazení kolekce nemá přednastavený formát zobrazení, je potřeba více práce, aby bylo možné poskytnout zpětnou vazbu k interakci uživatelů a sledovat výběr uživatele.
Důležité
Vzhledem k problému v Xcode 7 a macOS 10.11 (a novějším) nelze v souborech Storyboard (.storyboard) použít zobrazení kolekcí. V důsledku toho budete muset dál používat soubory .xib k definování zobrazení kolekce pro aplikace Xamarin.Mac. Další informace najdete v naší dokumentaci k zobrazením kolekcí .
Ladění nativních chybových ukončení
Když v datových vazbách uděláte chybu, může dojít k nativnímu chybovému ukončení v nespravovaném kódu a úplné selhání aplikace Xamarin.Mac s chybou SIGABRT
:
Během datové vazby obvykle existují čtyři hlavní příčiny nativních chybových ukončení:
- Datový model nedědí z
NSObject
nebo podtřídyNSObject
. - Nezpřístupnili jste vlastnost pro Objective-C použití atributu
[Export("key-name")]
. - Nezabalili jste změny v hodnotě
WillChangeValue
přístupového objektu aDidChangeValue
volání metody (určující stejný klíč jakoExport
atribut). - V nástroji Binding Inspector v Tvůrci rozhraní máte nesprávný nebo nesprávně zadaný klíč.
Dekódování chybového ukončení
Pojďme v naší datové vazbě způsobit nativní chybové ukončení, abychom mohli ukázat, jak ji najít a opravit. V Tvůrci rozhraní změníme naši vazbu prvního popisku v příkladu Zobrazení kolekce z Name
:Title
Uložme změnu, přepněte zpátky na Visual Studio pro Mac, aby se synchronizovala s Xcode a spustila naši aplikaci. Když se zobrazí zobrazení kolekce, aplikace se občas chybově ukončí s chybou SIGABRT
(jak je znázorněno ve výstupu aplikace v Visual Studio pro Mac), protože PersonModel
nezpřístupňuje vlastnost s klíčemTitle
:
Pokud se v výstupu aplikace posuneme na začátek chyby, uvidíme klíč k vyřešení problému:
Tento řádek nám říká, že klíč Title
neexistuje u objektu, se kterým je svázání. Pokud změníme vazbu zpět do Name
Tvůrce rozhraní, uložíme, synchronizujeme, znovu sestavíme a spustíme, aplikace se bez problému spustí podle očekávání.
Shrnutí
Tento článek se podrobně podíval na práci s datovými vazbami a kódováním klíč-hodnota v aplikaci Xamarin.Mac. Nejprve se podívala na zveřejnění třídy Objective-C C# pomocí kódování klíč-hodnota (KVC) a pozorování klíč-hodnota (KVO). Dále ukázala, jak používat třídu kompatibilní s KVO a vytvořit vazbu dat s prvky uživatelského rozhraní v Tvůrci rozhraní Xcode. Nakonec ukázala složitou datovou vazbu pomocí kontrolerů polí a kontrolerů stromové struktury.
Související odkazy
- Hello, Mac
- Standardní ovládací prvky
- Zobrazení tabulek
- Zobrazení osnovy
- Zobrazení kolekcí
- Průvodce programováním kódování klíč-hodnota
- Úvod do průvodce programováním s klíč-hodnota
- Úvod k programovacím tématům týkajícím se vazeb Cocoa
- Úvod do vazeb Cocoa – referenční dokumentace
- NSCollectionView
- pokyny pro lidské rozhraní systému macOS