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.

An example of the running app

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 RegisterExport 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 PersonModelinstanci .

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:

  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í tabulek, zobrazení osnovy a kolekce.
  2. 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#, Peoplena 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:

Adding a new view controller with a class named 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:

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

    Entering self dot Person dot Occupation for the Key Path.

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

    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 pole Počet spravovaných popisků zaměstnanců a textové pole.

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

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

  8. V rozevíracím seznamu Value Transformer vyberteNSNegateBoolean:

    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ého textu.

  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 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):

Hiding the number of employees for non-managers

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:

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

Laying out a new table view

Potřebujeme přidat řadič pole, který poskytuje svázaná data do naší tabulky, postupujte takto:

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

    Selecting an Array Controller from the Library

  2. Vyberte řadič pole v hierarchii rozhraní a přepněte na inspektor atributů:

    Selecting the Attributes Inspector

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

    Adding the required key paths to the Object Controller.

  4. Tím kontroleru pole řeknete, o čem spravuje pole a o které vlastnosti by měl být vystaven (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 cestuself.personModelArrayke klíči modelu:

    Entering a key path

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

  1. Vyberte zobrazení tabulky a kontrolu vazeb:

    Selecting the Table View and Binding Inspector.

  2. V rozevíracím seznamu Obsah tabulky vyberte Bind to a Array Controller. Zadejte arrangedObjects pro pole Klíč kontroleru:

    Defining the controller key

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

    Setting the model key path for the Employee column.

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

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

    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 spustíme aplikaci, tabulka se naplní naším polem PersonModels:

Running the application, which populates the array of 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:

Adding a new view controller with a class named 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:

Creating the outline view

Potřebujeme přidat kontroler stromu, který poskytuje svázaná data do osnovy, postupujte takto:

  1. Přetáhněte kontroler stromu z nástroje Library Inspector do editoru rozhraní:

    Selecting a Tree Controller from the Library

  2. V hierarchii rozhraní vyberte kontrolerstromu a přepněte na kontrolu atributů:

    Selecting the Attribute Inspector

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

    Adding the required key paths for PersonModel.

  4. To říká kontroleru stromové struktury, o čem spravuje pole a o které vlastnosti by měl být vystaven (prostřednictvím klíčů).

  5. V části Řadič stromu zadejte personModelArray pro podřízené položky do pole NumberOfEmployeesPočet a zadejte v isEmployee části 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 a Vlastník souboru. Zadejte cestuself.personModelArrayke klíči modelu:

    Editing the key path

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

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

    Selecting the Outline View and Binding Inspector.

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

    Setting the controller key

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

    Entering the model key path value objectValue dot Name.

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

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

    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 spustíme aplikaci, 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 ř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 :

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 nebo podtřídy NSObject.
  2. Nezpřístupnili jste vlastnost pro Objective-C použití atributu [Export("key-name")] .
  3. Nezabalili jste změny v hodnotě WillChangeValue přístupového objektu a DidChangeValue volání metody (určující stejný klíč jako Export atribut).
  4. 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

Editing the binding key

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:

Example of a binding error

Pokud se v výstupu aplikace posuneme na začátek chyby, 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, 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.