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í, které umožňuje datové vazby k prvkům uživatelského rozhraní v Tvůrci rozhraní Xcode.

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ých vazeb, které vývojář pracuje v Objective-CXcode . Vzhledem k tomu, že Xamarin.Mac se 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 aplikací.

An example of the running app

V tomto článku se podíváme na základy práce s kódováním klíč-hodnota a datovými vazbami v aplikaci Xamarin.Mac. Důrazně doporučujeme, abyste nejprve prošli článek Hello, Mac , konkrétně úvod do Xcode a Interface Builder a Outlets a Actions , protože se zabývá klíčovými koncepty a technikami, které budeme používat v tomto článku.

Můžete se také podívat na metody nebo třídy jazyka C#, které najdete v Objective-C dokumentu Xamarin.Mac Internals . Vysvětluje Register také atributy a Export 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 kódováním klíč-hodnota v aplikaci Xamarin.Mac získáte přístup k dalším funkcím macOS (dříve označovaným jako OS X), jako je pozorová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 aplikací.

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. Třída pak musí dědit z NSObject (nebo podtřídy, která dědí z NSObject), přidá několik základních metod, které umožňují třídě, aby byla kompatibilní s KVC. [Export("Name")] Dále atribut zveřejň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é Key-Value Pozorované změny hodnoty vlastnosti, musí příslušenství zabalit změny jeho hodnoty do WillChangeValue 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 k 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 hodnotou klíče. 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 Name uvedenému příkladu by tedy byla hodnota Name klíče vlastnosti PersonModel třídy. Klíč a název vlastnosti, kterou zveřejňuje, 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 pro procházení. Vlastnost prvního klíče v posloupnosti je relativní vůči příjemci a každý další klíč se vyhodnotí vzhledem k hodnotě předchozí vlastnosti. Stejným způsobem používáte zápis tečky k procházení objektu a jeho vlastností ve třídě jazyka C#.

Pokud například rozbalíte PersonModel třídu a přidáte 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"));

To by vrátilo hodnotu Name vlastnosti pro danou PersonModelinstanci .

Nastavení hodnot pomocí kódování klíč-hodnota

SetValueForKey Podobně je nastavena hodnota pro zadaný klíč (jako aNSString), vzhledem k instanci třídy KVC přijímající 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"));

Změnila by hodnotu Name vlastnosti na Jane Doe.

Sledování změn hodnot

Pomocí pozorování klíč-hodnota (KVO) můžete pozorovatele připojit ke konkrétnímu klíči třídy kompatibilní s KVC a být upozorněni kdykoliv na změnu hodnoty 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 se zapíše do konzoly.

Další informace naleznete v úvodu společnosti Apple do 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 kompatibilní třídu pro vytvoření vazby 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 snadněji udržovatelná. Výrazně také zmenšíte množství kódu, který se musí zapsat.

Definování datového modelu

Než budete moct vytvořit vazbu prvku uživatelského rozhraní v Tvůrci rozhraní, musíte mít třídu kompatibilní s KVC/KVO definovanou v aplikaci Xamarin.Mac, 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é změny 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šinu funkcí této třídy jsme probrali 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 dodatků, které byly provedeny, aby tato třída fungovala jako datový model pro kontrolery polí a stromové kontrolery (které později použijeme k vytvoření vazby stromových zobrazení dat, 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) tak, aby se k nim zaměstnanci mohli připojit:

private NSMutableArray _people = new NSMutableArray();
...

[Export("personModelArray")]
public NSArray People {
    get { return _people; }
}

Tady je potřeba si uvědomit dvě věci:

  1. Místo standardního pole nebo kolekce jazyka C# jsme použiliNSMutableArray, protože se jedná o požadavek na vytvoření vazby dat s ovládacími prvky AppKitu, jako jsou zobrazení tabulky, zobrazení osnovy a kolekce.
  2. Pole zaměstnanců jsme zpřístupnili tak, že ho přetypujeme pro NSArray účely datových vazeb a změnili jsme jeho formátovaný název jazyka C#, Peoplena ten, který očekává datová vazba, personModelArray ve formuláři {class_name}Array (všimněte si, že první znak byl složen z malých písmen).

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

To umožňuje řadičům požadovat a upravit data, která zobrazují. Podobně jako výše uvedené NSArray mají tyto zásady vytváření názvů velmi specifické (liší se od typický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 Icon vlastnost spoléhá na hodnotu isManager vlastnosti, změny isManager vlastnosti nemusí být promítnuty do prvků uživatelského rozhraní vázaného Icon na 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, že kromě vlastního isManager klíče odesílá přístupové objekty i WillChangeValueDidChangeValue zprávy pro Icon klíč, aby se změny zobrazily i.

Ve zbývající části tohoto článku použijeme PersonModel datový model.

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, která se dá použít k úpravě PersonModel toho, co jsme definovali výše. 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:

Adding a new view controller with a class named SimpleViewController.

Potom se vraťte do Visual Studio pro Mac, upravte soubor SimpleViewController.cs (který byl automaticky přidán do našeho projektu) a zveřejníme instanciPersonModel, se kterou budeme svázat formulář. 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 nějak takto:

Editing the storyboard in Xcode

Chcete-li vytvořit vazbu formuláře na PersonModel formulář, který jsme odhalili prostřednictvím Person klíče, postupujte takto:

  1. Vyberte textové pole jméno zaměstnance a přepněte na kontrolu vazeb.

  2. 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:

    Entering self dot person dot name for the Key Path.

  3. Vyberte textové pole povolá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:

    Entering self dot Person dot Occupation for the Key Path.

  4. Vyberte Employee is a Manager Checkbox and check the Bind to box and select Simple View Controller from the dropdown. Dále zadejte self.Person.isManager cestu ke klíči:

    Entering self dot Person dot isManager for the Key Path.

  5. 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:

    Entering self dot Person dot NumberOfEmployees for the Key Path.

  6. Pokud zaměstnanec není manažerem, chceme skrýt popisek spravovaných zaměstnanci a textové pole.

  7. Zaškrtněte políčko Počet spravovaných popisků 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:

    Entering self dot Person dot isManager for the Key Path for non-managers.

  8. Vyberte NSNegateBoolean z rozevíracího seznamu Value Transformer :

    Selecting the NSNegateBoolean key transformation

  9. To říká datové vazbě, že popisek bude skrytý, pokud je falsehodnota isManager vlastnosti .

  10. Opakujte kroky 7 a 8 pro pole Počet zaměstnanců spravovaných textem.

  11. 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:

Showing an auto-populated form

Všechny změny provedené uživateli ve formuláři budou zapsány 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 se automaticky skryjí (prostřednictvím datové vazby):

Hiding the number of employees for non-managers

Datová vazba zobrazení tabulky

Teď, když máme základy datové vazby mimo cestu, pojďme se podívat 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:

Adding a new view controller with a class named TableViewController.

V dalším kroku upravíme soubor TableViewController.cs (který byl automaticky přidán do našeho projektu) a zveřejníme pole (NSArray) PersonModel tříd, se kterými budeme svázat formulář. 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 u výše uvedené třídy v části Definování datového modelu , zveřejnili jsme čtyři speciálně pojmenované veřejné metody, aby kontroler pole a nač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, poklikejte na soubor Main.storyboard a otevřete ho pro úpravy v Tvůrci rozhraní. Rozložení tabulky tak, aby vypadalo přibližně takto:

Laying out a new table view

Potřebujeme přidat kontroler pole , který poskytuje svázaná data do naší tabulky, udělejte toto:

  1. Přetáhněte kontroler pole z inspektoru knihovny do editoru rozhraní:

    Selecting an Array Controller from the Library

  2. V hierarchii rozhraní vyberte kontroler pole a přepněte na inspektor atributů:

    Selecting the Attributes Inspector

  3. Zadejte PersonModelnázev třídy, klikněte na tlačítko Plus a přidejte tři klíče. Pojmenujte je NameOccupation a isManager:

    Adding the required key paths to the Object Controller.

  4. To říká řadiči pole, co spravuje pole a které vlastnosti by měl zveřejnit (prostřednictvím klíčů).

  5. 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 ke klíčiself.personModelArraymodelu:

    Entering a key path

  6. Tím se sváže kontroler pole s polem PersonModels , které jsme vystavovali na kontroleru zobrazení.

Teď potřebujeme vytvořit vazbu zobrazení tabulky s kontrolerem pole:

  1. Vyberte zobrazení tabulky a kontrolu vazeb:

    Selecting the Table View and Binding Inspector.

  2. V rozevíracím seznamu Obsah tabulky vyberte Vytvořit vazbu akontroler pole. Zadejte arrangedObjects pole Klíč kontroleru :

    Defining the controller key

  3. Vyberte buňku zobrazení tabulky ve sloupci Zaměstnanec . V inspektoru Vazby v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu kbuňce a Zobrazení buněk tabulky. Zadejte objectValue.Namecestu ke klíči modelu:

    Setting the model key path for the Employee column.

  4. objectValue je aktuální PersonModel v poli, které spravuje kontroler pole.

  5. Vyberte buňku zobrazení tabulky ve sloupci Povolání . V inspektoru Vazby v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu kbuňce a Zobrazení buněk tabulky. Zadejte objectValue.Occupationcestu ke klíči modelu:

    Setting the model key path for the Occupation column.

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

Pokud aplikaci spustíme, tabulka se naplní naším polem PersonModels:

Running the application, which populates the array of PersonModels.

Datová vazba zobrazení osnovy

datová vazba proti zobrazení osnovy je velmi podobná vazbě vůči zobrazení tabulky. Klíčovým rozdílem je to, že místo kontroleru pole použijeme kontroler stromu k poskytování vázaných dat do zobrazení osnovy. Další informace o práci se zobrazeními osnovy najdete v naší dokumentaci k zobrazením osnovy .

Nejprve přidáme nový kontroler zobrazení do souboru Main.storyboard v Tvůrci rozhraní a pojmenujeme jeho třídu OutlineViewController:

Adding a new view controller with a class named OutlineViewController.

V dalším kroku upravíme soubor OutlineViewController.cs (který byl automaticky přidán do našeho projektu) a zveřejníme pole (NSArray) PersonModel tříd, se kterými budeme svázat formulář. 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 třídě výše v části Definování datového modelu , zveřejnili jsme č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:

Creating the outline view

Potřebujeme přidat kontroler stromu , který poskytuje svázaná data do osnovy, udělejte toto:

  1. Přetáhněte stromový kontroler z inspektoru knihovny do editoru rozhraní:

    Selecting a Tree Controller from the Library

  2. V hierarchii rozhraní vyberte kontroler stromu a přepněte na inspektor atributů:

    Selecting the Attribute Inspector

  3. Zadejte PersonModelnázev třídy, klikněte na tlačítko Plus a přidejte tři klíče. Pojmenujte je NameOccupation a isManager:

    Adding the required key paths for PersonModel.

  4. To říká kontroleru stromu, co spravuje pole a které vlastnosti by měl zveřejnit (prostřednictvím klíčů).

  5. V části Kontroler stromu zadejte personModelArraypodřízené položky do NumberOfEmployees pole Počet a zadejte isEmployee do pole List:

    Setting the Tree Controller key paths

  6. 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.

  7. Přepněte na kontrolu vazeb a v části Pole obsahu vyberte Vytvořit vazbu avlastníka souboru. Zadejte cestu ke klíčiself.personModelArraymodelu:

    Editing the key path

  8. Tím se prováže kontroler stromu na pole PersonModels , které jsme vystavovali na kontroleru zobrazení.

Teď potřebujeme vytvořit vazbu zobrazení osnovy na řadič stromu, udělejte toto:

  1. Vyberte zobrazení osnovy a v inspektoru vazby vyberte:

    Selecting the Outline View and Binding Inspector.

  2. V rozevíracím seznamu Obsah zobrazení osnovy vyberte Vytvořit vazbu k řadiči stromu a Vytvořit vazbu. Zadejte arrangedObjects pole Klíč kontroleru :

    Setting the controller key

  3. Vyberte buňku zobrazení tabulky ve sloupci Zaměstnanec . V inspektoru Vazby v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu kbuňce a Zobrazení buněk tabulky. Zadejte objectValue.Namecestu ke klíči modelu:

    Entering the model key path value objectValue dot Name.

  4. objectValue je aktuální PersonModel v poli spravovaném kontrolerem stromu.

  5. Vyberte buňku zobrazení tabulky ve sloupci Povolání . V inspektoru Vazby v rozevíracím seznamu Hodnota vyberte Vytvořit vazbu kbuňce a Zobrazení buněk tabulky. Zadejte objectValue.Occupationcestu ke klíči modelu:

    Entering the model key path value objectValue dot Occupation.

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

Pokud aplikaci spustíme, osnova se naplní naším polem PersonModels:

Running the application, which populates our array of PersonModels.

Datová vazba zobrazení kolekce

Datová vazba se zobrazením kolekce je velmi podobná vazbě se zobrazením tabulky, protože kontroler 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živatelů.

Důležité

Vzhledem k problému v Xcode 7 a macOS 10.11 (a novějším) nejde 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í

Chyba ve vašich datových vazbách může vést k nativnímu chybovému ukončení v nespravovaném kódu a způsobit, že vaše aplikace Xamarin.Mac selže úplně s chybou SIGABRT :

Example of a native crash dialog box

Během datové vazby obvykle existují čtyři hlavní příčiny nativních chybových ukončení:

  1. Datový model nedědí z NSObject podtřídy NSObject.
  2. Vlastnost jste nezpřístupnili pro Objective-C použití atributu [Export("key-name")] .
  3. Nezabalili jste změny hodnoty přístupového objektu do WillChangeValue volání metody a DidChangeValue metody (určení stejného klíče jako Export atribut).
  4. V Tvůrci rozhraní v Nástroji pro kontrolu vazeb máte chybný nebo chybně zadaný klíč.

Dekódování chybového ukončení

V naší datové vazbě způsobíme nativní chybové ukončení, abychom mohli ukázat, jak ho najít a opravit. V Tvůrci rozhraní změníme naši vazbu prvního popisku v příkladu zobrazení kolekce z Name na Title:

Editing the binding key

Uložme změnu, vraťme se na Visual Studio pro Mac, aby se synchronizovala s Xcodem a spustila se naše aplikace. Když se zobrazí zobrazení kolekce, aplikace dojde k chybovému ukončení aplikace 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:

Example of a binding error

Pokud se posuneme na začátek chyby ve výstupu aplikace , uvidíme klíč k vyřešení problému:

Finding the issue in the error log

Tento řádek nám říká, že klíč Title neexistuje u objektu, ke kterému jsme vázáni. Pokud změníme vazbu zpět v Name Tvůrci rozhraní, uložíme, synchronizujeme, znovu sestavíme a spustíme, aplikace se bez problémů spustí podle očekávání.

Souhrn

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íval na zveřejnění třídy Objective-C jazyka 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í řadičů polí a řadičů stromu.