Liaison de données et codage clé-valeur dans Xamarin.Mac
Cet article traite de l’utilisation du codage clé-valeur et de l’observation clé-valeur pour permettre la liaison de données aux éléments d’interface utilisateur dans le Générateur d’interface de Xcode.
Vue d’ensemble
Lorsque vous utilisez C# et .NET dans une application Xamarin.Mac, vous avez accès aux mêmes techniques de codage clé-valeur et de liaison de données qu’un développeur travaillant dans Objective-C et Xcode . Étant donné que Xamarin.Mac s’intègre directement à Xcode, vous pouvez utiliser le Générateur d’interface de Xcode pour lier des données avec des éléments d’interface utilisateur au lieu d’écrire du code.
En utilisant des techniques de codage clé-valeur et de liaison de données dans votre application Xamarin.Mac, vous pouvez réduire considérablement la quantité de code que vous devez écrire et gérer pour remplir et utiliser des éléments d’interface utilisateur. Vous bénéficiez également d’un découplage supplémentaire de vos données de stockage (modèle de données) de votre interface utilisateur frontale (modèle-vue-contrôleur), ce qui facilite la maintenance et la conception d’applications plus flexibles.
Dans cet article, nous allons aborder les principes fondamentaux de l’utilisation du codage clé-valeur et de la liaison de données dans une application Xamarin.Mac. Il est fortement suggéré que vous travaillez tout d’abord dans l’article Hello, Mac , en particulier les sections Introduction to Xcode and Interface Builder et Outlets and Actions , car elle couvre les concepts et techniques clés que nous utiliserons dans cet article.
Vous pouvez également examiner les classes /méthodes C# exposantes dans Objective-C la section du document interne Xamarin.Mac , ainsi que les Register
Export
attributs utilisés pour connecter vos classes C# à des objets et des Objective-C éléments d’interface utilisateur.
Qu’est-ce que le codage clé-valeur ?
Le codage clé-valeur (KVC) est un mécanisme permettant d’accéder indirectement aux propriétés d’un objet, à l’aide de clés (chaînes spécialement mises en forme) pour identifier les propriétés au lieu de les accéder via des variables d’instance ou des méthodes d’accesseur (get/set
). En implémentant des accesseurs conformes de codage clé-valeur dans votre application Xamarin.Mac, vous accédez à d’autres fonctionnalités macOS (anciennement OS X) telles que l’observation de valeur clé (KVO), la liaison de données, les données principales, les liaisons Cocoa et la scriptabilité.
En utilisant des techniques de codage clé-valeur et de liaison de données dans votre application Xamarin.Mac, vous pouvez réduire considérablement la quantité de code que vous devez écrire et gérer pour remplir et utiliser des éléments d’interface utilisateur. Vous bénéficiez également d’un découplage supplémentaire de vos données de stockage (modèle de données) de votre interface utilisateur frontale (modèle-vue-contrôleur), ce qui facilite la maintenance et la conception d’applications plus flexibles.
Par exemple, examinons la définition de classe suivante d’un objet conforme 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 ()
{
}
}
}
Tout d’abord, l’attribut [Register("PersonModel")]
inscrit la classe et l’expose à Objective-C. Ensuite, la classe doit hériter ( NSObject
ou d’une sous-classe qui hérite de NSObject
), cela ajoute plusieurs méthodes de base qui permettent à la classe d’être conforme KVC. Ensuite, l’attribut [Export("Name")]
expose la Name
propriété et définit la valeur clé qui sera utilisée ultérieurement pour accéder à la propriété via les techniques KVC et KVO.
Enfin, pour pouvoir être en mesure d’être des modifications observées par clé à la valeur de la propriété, l’accesseur doit encapsuler les modifications apportées à sa valeur et WillChangeValue
DidChangeValue
les appels de méthode (en spécifiant la même clé que l’attribut Export
). Par exemple :
set {
WillChangeValue ("Name");
_name = value;
DidChangeValue ("Name");
}
Cette étape est très importante pour la liaison de données dans le Générateur d’interface de Xcode (comme nous le verrons plus loin dans cet article).
Pour plus d’informations, consultez le Guide de programmation de codage clé-valeur d’Apple.
Clés et chemins de clés
Une clé est une chaîne qui identifie une propriété spécifique d’un objet. En règle générale, une clé correspond au nom d’une méthode d’accesseur dans un objet conforme au codage clé-valeur. Les clés doivent utiliser l’encodage ASCII, généralement commencer par une lettre minuscule et ne pas contenir d’espace blanc. Ainsi, étant donné l’exemple ci-dessus, Name
il s’agit d’une valeur clé de Name
propriété de la PersonModel
classe. La clé et le nom de la propriété qu’ils exposent n’ont pas besoin d’être identiques, mais dans la plupart des cas, ils sont.
Un chemin de clé est une chaîne de clés séparées par des points utilisées pour spécifier une hiérarchie de propriétés d’objet à parcourir. La propriété de la première clé de la séquence est relative au récepteur, et chaque clé suivante est évaluée par rapport à la valeur de la propriété précédente. De la même façon, vous utilisez la notation par points pour parcourir un objet et ses propriétés dans une classe C#.
Par exemple, si vous avez développé la classe et ajouté Child
la PersonModel
propriété :
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 ()
{
}
}
}
Le chemin d’accès à la clé du nom de l’enfant serait self.Child.Name
ou simplement Child.Name
(en fonction de la façon dont la valeur de clé était utilisée).
Obtention de valeurs à l’aide du codage clé-valeur
La ValueForKey
méthode retourne la valeur de la clé spécifiée (en tant que NSString
), par rapport à l’instance de la classe KVC qui reçoit la requête. Par exemple, s’il s’agit Person
d’une instance de la PersonModel
classe définie ci-dessus :
// Read value
var name = Person.ValueForKey (new NSString("Name"));
Cela renvoie la valeur de la Name
propriété pour cette instance de PersonModel
.
Définition de valeurs à l’aide du codage clé-valeur
De même, définissez SetValueForKey
la valeur de la clé spécifiée (en tant que NSString
), par rapport à l’instance de la classe KVC qui reçoit la requête. Par conséquent, à l’aide d’une instance de la PersonModel
classe, comme indiqué ci-dessous :
// Write value
Person.SetValueForKey(new NSString("Jane Doe"), new NSString("Name"));
Modifie la valeur de la Name
propriété en Jane Doe
.
Observation des modifications de valeur
À l’aide de l’observation de valeur clé (KVO), vous pouvez attacher un observateur à une clé spécifique d’une classe conforme KVC et être averti à tout moment de la modification de la valeur de cette clé (à l’aide de techniques KVC ou d’accès direct à la propriété donnée dans le code C#). Par exemple :
// Watch for the name value changing
Person.AddObserver ("Name", NSKeyValueObservingOptions.New, (sender) => {
// Inform caller of selection change
Console.WriteLine("New Name: {0}", Person.Name)
});
À présent, chaque fois que la Name
propriété de l’instance Person
de la PersonModel
classe est modifiée, la nouvelle valeur est écrite dans la console.
Pour plus d’informations, consultez le Guide de programmation d’observation des valeurs clés d’Apple.
Liaison de données
Les sections suivantes montrent comment utiliser un codage clé-valeur et une classe conforme d’observation de clé-valeur pour lier des données à des éléments d’interface utilisateur dans le Générateur d’interface de Xcode, au lieu de lire et d’écrire des valeurs à l’aide du code C#. De cette façon, vous séparez votre modèle de données des vues utilisées pour les afficher, ce qui rend l’application Xamarin.Mac plus flexible et plus facile à gérer. Vous réduisez également considérablement la quantité de code qui doit être écrite.
Définition de votre modèle de données
Avant de pouvoir lier des données à un élément d’interface utilisateur dans Interface Builder, vous devez disposer d’une classe conforme KVC/KVO définie dans votre application Xamarin.Mac pour agir comme modèle de données pour la liaison. Le modèle de données fournit toutes les données qui seront affichées dans l’interface utilisateur et reçoit toutes les modifications apportées aux données que l’utilisateur effectue dans l’interface utilisateur lors de l’exécution de l’application.
Par exemple, si vous écriviez une application qui gérait un groupe d’employés, vous pouvez utiliser la classe suivante pour définir le modèle de données :
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
}
}
La plupart des fonctionnalités de cette classe ont été abordées dans la section De codage clé-valeur ci-dessus. Toutefois, examinons quelques éléments spécifiques et quelques ajouts qui ont été effectués pour permettre à cette classe d’agir en tant que modèle de données pour les contrôleurs de tableau et les contrôleurs d’arborescence (que nous utiliserons ultérieurement pour lier des arborescences, des vues hiérarchiques et des vues de collection).
Tout d’abord, étant donné qu’un employé peut être un responsable, nous avons utilisé un (en particulier un NSArray
NSMutableArray
pour que les valeurs puissent être modifiées) pour permettre aux employés qu’ils ont gérés d’être attachés à eux :
private NSMutableArray _people = new NSMutableArray();
...
[Export("personModelArray")]
public NSArray People {
get { return _people; }
}
Deux points à noter ici :
- Nous avons utilisé un
NSMutableArray
tableau ou une collection C# standard, car il s’agit d’une exigence de liaison de données à des contrôles AppKit tels que les vues de table, les vues hiérarchiques et les collections. - Nous avons exposé le tableau des employés en le castant à des
NSArray
fins de liaison de données et modifié son nom mis en forme C#,People
en un nom attendu par la liaison de données,personModelArray
sous la forme {class_name}Array (notez que le premier caractère a été mis en minuscules).
Ensuite, nous devons ajouter des méthodes publiques spécialement nommées pour prendre en charge les contrôleurs de tableau et les contrôleurs d’arborescence :
[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");
}
Ils permettent aux contrôleurs de demander et de modifier les données qu’ils affichent. Comme l’exposé NSArray
ci-dessus, ceux-ci ont une convention d’affectation de noms très spécifique (qui diffère des conventions d’affectation de noms C# classiques) :
addObject:
- Ajoute un objet au tableau.insertObject:in{class_name}ArrayAtIndex:
- Où{class_name}
est le nom de votre classe. Cette méthode insère un objet dans le tableau à un index donné.removeObjectFrom{class_name}ArrayAtIndex:
- Où{class_name}
est le nom de votre classe. Cette méthode supprime l’objet du tableau à un index donné.set{class_name}Array:
- Où{class_name}
est le nom de votre classe. Cette méthode vous permet de remplacer le transport existant par un nouveau.
À l’intérieur de ces méthodes, nous avons encapsulé les modifications apportées au tableau WillChangeValue
et DidChangeValue
aux messages pour la conformité KVO.
Enfin, étant donné que la Icon
propriété s’appuie sur la valeur de la isManager
propriété, les modifications apportées à la isManager
propriété peuvent ne pas être reflétées dans les Icon
éléments d’interface utilisateur liés aux données (pendant KVO) :
[Export("Icon")]
public NSImage Icon {
get {
if (isManager) {
return NSImage.ImageNamed ("group.png");
} else {
return NSImage.ImageNamed ("user.png");
}
}
}
Pour corriger cela, nous utilisons le code suivant :
[Export("isManager")]
public bool isManager {
get { return _isManager; }
set {
WillChangeValue ("isManager");
WillChangeValue ("Icon");
_isManager = value;
DidChangeValue ("isManager");
DidChangeValue ("Icon");
}
}
Notez qu’en plus de sa propre clé, l’accesseur isManager
envoie également les messages et DidChangeValue
les WillChangeValue
messages de la Icon
clé afin qu’il voit également la modification.
Nous allons utiliser le PersonModel
modèle de données dans le reste de cet article.
Liaison de données simple
Avec notre modèle de données défini, examinons un exemple simple de liaison de données dans le Générateur d’interface de Xcode. Par exemple, nous allons ajouter un formulaire à notre application Xamarin.Mac qui peut être utilisée pour modifier le PersonModel
formulaire que nous avons défini ci-dessus. Nous allons ajouter quelques champs de texte et une case à cocher pour afficher et modifier les propriétés de notre modèle.
Tout d’abord, nous allons ajouter un nouveau contrôleur de vue à notre fichier Main.storyboard dans Interface Builder et nommer sa classe SimpleViewController
:
Ensuite, revenez à Visual Studio pour Mac, modifiez le fichier SimpleViewController.cs (qui a été ajouté automatiquement à notre projet) et exposez une instance du PersonModel
formulaire auquel nous allons lier les données. Ajoutez le code suivant :
private PersonModel _person = new PersonModel();
...
[Export("Person")]
public PersonModel Person {
get {return _person; }
set {
WillChangeValue ("Person");
_person = value;
DidChangeValue ("Person");
}
}
Ensuite, lorsque la vue est chargée, nous allons créer une instance de notre PersonModel
instance et la remplir avec ce code :
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;
}
Maintenant, nous devons créer notre formulaire, double-cliquez sur le fichier Main.storyboard pour l’ouvrir pour modification dans Interface Builder. Disposition du formulaire pour qu’il ressemble à ce qui suit :
Pour lier le formulaire au PersonModel
formulaire que nous avons exposé via la Person
clé, procédez comme suit :
Sélectionnez le champ texte nom de l’employé et basculez vers l’inspecteur liaisons.
Cochez la case Lier à et sélectionnez Contrôleur d’affichage simple dans la liste déroulante. Entrez
self.Person.Name
ensuite le chemin d’accès à la clé :Sélectionnez le champ Texte d’occupation et case activée la zone Lier à la zone, puis sélectionnez Contrôleur d’affichage simple dans la liste déroulante. Entrez
self.Person.Occupation
ensuite le chemin d’accès à la clé :Sélectionnez l’employé comme case à cocher Gestionnaire et case activée la case Lier à la zone, puis sélectionnez Contrôleur d’affichage simple dans la liste déroulante. Entrez
self.Person.isManager
ensuite le chemin d’accès à la clé :Sélectionnez le champ Texte managé du nombre d’employés et case activée la zone Lier à, puis sélectionnez Contrôleur d’affichage simple dans la liste déroulante. Entrez
self.Person.NumberOfEmployees
ensuite le chemin d’accès à la clé :Si l’employé n’est pas un responsable, nous voulons masquer le nombre d’employés gérés étiquette et champ texte.
Sélectionnez le nombre d’employés gérés label, développez la désactivation masquée et case activée la zone Lier à, puis sélectionnez Contrôleur d’affichage simple dans la liste déroulante. Entrez
self.Person.isManager
ensuite le chemin d’accès à la clé :Sélectionnez
NSNegateBoolean
dans la liste déroulante Transformateur de valeur :Cela indique à la liaison de données que l’étiquette sera masquée si la valeur de la
isManager
propriété estfalse
.Répétez les étapes 7 et 8 pour le champ Texte managé du nombre d’employés.
Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.
Si vous exécutez l’application, les valeurs de la Person
propriété remplissent automatiquement notre formulaire :
Toutes les modifications apportées par les utilisateurs au formulaire sont réécrites dans la Person
propriété dans le contrôleur de vue. Par exemple, la désélection de l’employé est un responsable met à jour l’instance Person
de notre PersonModel
et le champ d’étiquette managée du nombre d’employés et de champ de texte sont masqués automatiquement (via la liaison de données) :
Liaison de données d’affichage de table
Maintenant que nous disposons des principes de base de la liaison de données, examinons une tâche de liaison de données plus complexe à l’aide d’un contrôleur de tableau et d’une liaison de données vers une vue table. Pour plus d’informations sur l’utilisation des vues de table, consultez notre documentation sur les vues de table.
Tout d’abord, nous allons ajouter un nouveau contrôleur de vue à notre fichier Main.storyboard dans Interface Builder et nommer sa classe TableViewController
:
Ensuite, nous allons modifier le fichier TableViewController.cs (qui a été automatiquement ajouté à notre projet) et exposer un tableau (NSArray
) de PersonModel
classes auxquelles nous allons lier nos données. Ajoutez le code suivant :
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");
}
Comme nous l’avons fait sur la PersonModel
classe ci-dessus dans la section Définition de votre modèle de données, nous avons exposé quatre méthodes publiques spécialement nommées afin que le contrôleur de tableau et lisent et écrivent des données à partir de notre collection de PersonModels
.
Ensuite, lorsque la vue est chargée, nous devons remplir notre tableau avec ce code :
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"));
}
Maintenant, nous devons créer notre affichage table, double-cliquez sur le fichier Main.storyboard pour l’ouvrir pour modification dans le Générateur d’interface. Disposition du tableau pour qu’elle ressemble à ce qui suit :
Nous devons ajouter un contrôleur de tableau pour fournir des données liées à notre table, procédez comme suit :
Faites glisser un contrôleur de tableau à partir de l’inspecteur de bibliothèque vers l’éditeur d’interface :
Sélectionnez Le contrôleur de tableau dans la hiérarchie d’interface et basculez vers l’inspecteur d’attribut :
Entrez
PersonModel
le nom de la classe, cliquez sur le bouton Plus et ajoutez trois clés. Nommez-lesName
,Occupation
etisManager
:Cela indique au contrôleur de tableau ce qu’il gère un tableau et les propriétés qu’il doit exposer (via les clés).
Basculez vers l’inspecteur liaisons et, sous Le tableau de contenu, sélectionnez Lier au contrôleur de vue table et liaison. Entrez un chemin de clé de modèle de
self.personModelArray
:Cela lie le contrôleur de tableau au tableau de celui que
PersonModels
nous avons exposé sur notre contrôleur de vue.
Nous devons maintenant lier notre vue table au contrôleur de tableau, procédez comme suit :
Sélectionnez l’affichage table et l’inspecteur de liaison :
Sous la liste déroulante Contenu de la table, sélectionnez Lier à et Contrôleur de tableau. Entrez
arrangedObjects
le champ Clé du contrôleur :Sélectionnez la cellule Table View sous la colonne Employee . Dans l’inspecteur liaisons, sous la valeur de la valeur, sélectionnez Lier à et Table Cell View. Entrez
objectValue.Name
le chemin de la clé de modèle :objectValue
est le courantPersonModel
dans le tableau géré par le contrôleur de tableau.Sélectionnez la cellule Table View sous la colonne Occupation . Dans l’inspecteur liaisons, sous la valeur de la valeur, sélectionnez Lier à et Table Cell View. Entrez
objectValue.Occupation
le chemin de la clé de modèle :Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.
Si nous exécutons l’application, la table est remplie avec notre tableau de PersonModels
:
Liaison de données d’affichage hiérarchique
la liaison de données par rapport à un mode Plan est très similaire à la liaison à un affichage table. La principale différence est que nous allons utiliser un contrôleur d’arborescence au lieu d’un contrôleur de tableau pour fournir les données liées à la vue hiérarchique. Pour plus d’informations sur l’utilisation des vues hiérarchiques, consultez notre documentation sur les vues hiérarchiques .
Tout d’abord, nous allons ajouter un nouveau contrôleur de vue à notre fichier Main.storyboard dans Interface Builder et nommer sa classe OutlineViewController
:
Ensuite, nous allons modifier le fichier OutlineViewController.cs (qui a été automatiquement ajouté à notre projet) et exposer un tableau (NSArray
) de PersonModel
classes auxquelles nous allons lier nos données. Ajoutez le code suivant :
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");
}
Comme nous l’avons fait sur la PersonModel
classe ci-dessus dans la section Définition de votre modèle de données, nous avons exposé quatre méthodes publiques spécialement nommées afin que le contrôleur d’arborescence et lisent et écrivent des données à partir de notre collection de PersonModels
.
Ensuite, lorsque la vue est chargée, nous devons remplir notre tableau avec ce code :
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);
}
Maintenant, nous devons créer notre mode Plan, double-cliquez sur le fichier Main.storyboard pour l’ouvrir pour modification dans Interface Builder. Disposition du tableau pour qu’elle ressemble à ce qui suit :
Nous devons ajouter un contrôleur d’arborescence pour fournir des données liées à notre plan, procédez comme suit :
Faites glisser un contrôleur d’arborescence de l’inspecteur de bibliothèque vers l’éditeur d’interface :
Sélectionnez Le contrôleur d’arborescence dans la hiérarchie d’interface et basculez vers l’inspecteur d’attribut :
Entrez
PersonModel
le nom de la classe, cliquez sur le bouton Plus et ajoutez trois clés. Nommez-lesName
,Occupation
etisManager
:Cela indique au contrôleur d’arborescence ce qu’il gère un tableau et les propriétés qu’il doit exposer (via les clés).
Sous la section Du contrôleur d’arborescence, entrez pour enfants, entrez
NumberOfEmployees
personModelArray
sous le nombre et entrezisEmployee
sous Feuille :Cela indique au contrôleur d’arborescence où trouver les nœuds enfants, le nombre de nœuds enfants présents et si le nœud actuel possède des nœuds enfants.
Basculez vers l’inspecteur de liaisons et, sous Tableau de contenu, sélectionnez Lier au propriétaire du fichier et à celui du fichier. Entrez un chemin de clé de modèle de
self.personModelArray
:Cela lie le contrôleur d’arborescence au tableau de
PersonModels
celui que nous avons exposé sur notre contrôleur de vue.
Nous devons maintenant lier notre mode Plan au contrôleur d’arborescence, procédez comme suit :
Sélectionnez le mode Plan et, dans l’inspecteur de liaison, sélectionnez :
Sous la liste déroulante Du contenu de l’affichage hiérarchique, sélectionnez Lier à et Tree Controller. Entrez
arrangedObjects
le champ Clé du contrôleur :Sélectionnez la cellule Table View sous la colonne Employee . Dans l’inspecteur liaisons, sous la valeur de la valeur, sélectionnez Lier à et Table Cell View. Entrez
objectValue.Name
le chemin de la clé de modèle :objectValue
est le courantPersonModel
dans le tableau géré par le contrôleur d’arborescence.Sélectionnez la cellule Table View sous la colonne Occupation . Dans l’inspecteur liaisons, sous la valeur de la valeur, sélectionnez Lier à et Table Cell View. Entrez
objectValue.Occupation
le chemin de la clé de modèle :Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.
Si nous exécutons l’application, le plan est rempli avec notre tableau de PersonModels
:
Liaison de données de vue de collecte
La liaison de données avec une vue collection est très similaire à la liaison avec un affichage table, car un contrôleur de tableau est utilisé pour fournir des données pour la collection. Étant donné que l’affichage collection n’a pas de format d’affichage prédéfini, davantage de travail est nécessaire pour fournir des commentaires d’interaction utilisateur et suivre la sélection de l’utilisateur.
Important
En raison d’un problème dans Xcode 7 et macOS 10.11 (et ultérieur), les vues de collection ne peuvent pas être utilisées à l’intérieur d’un fichier Storyboard (.storyboard). Par conséquent, vous devez continuer à utiliser des fichiers .xib pour définir vos vues de collection pour vos applications Xamarin.Mac. Pour plus d’informations, consultez notre documentation Vues de collection.
Débogage des incidents natifs
Une erreur dans vos liaisons de données peut entraîner un plantage natif dans du code non managé et provoquer l’échec complet de votre application Xamarin.Mac avec une SIGABRT
erreur :
Il existe généralement quatre causes principales pour les blocages natifs lors de la liaison de données :
- Votre modèle de données n’hérite pas ou d’une
NSObject
sous-classe deNSObject
. - Vous n’avez pas exposé votre propriété à Objective-C l’utilisation de l’attribut
[Export("key-name")]
. - Vous n’avez pas inclus les modifications apportées à la valeur
WillChangeValue
de l’accesseur etDidChangeValue
les appels de méthode (en spécifiant la même clé que l’attributExport
). - Vous avez une clé incorrecte ou mal typée dans l’inspecteur de liaison dans le Générateur d’interface.
Décodage d’un incident
Nous allons provoquer un blocage natif dans notre liaison de données afin de pouvoir montrer comment le localiser et le corriger. Dans le Générateur d’interface, nous allons modifier notre liaison de première étiquette dans l’exemple De vue Collection de Name
:Title
Nous allons enregistrer la modification, revenir à Visual Studio pour Mac pour synchroniser avec Xcode et exécuter notre application. Lorsque l’affichage collection s’affiche, l’application se bloque momentanément avec une SIGABRT
erreur (comme indiqué dans la sortie de l’application dans Visual Studio pour Mac), car elle PersonModel
n’expose pas de propriété avec la clé Title
:
Si nous défilons vers le haut de l’erreur dans la sortie de l’application, nous pouvons voir la clé pour résoudre le problème :
Cette ligne nous indique que la clé Title
n’existe pas sur l’objet auquel nous nous liez. Si nous revenons à la liaison Name
dans Interface Builder, enregistrez, synchronisez, régénérez et exécutez, l’application s’exécute comme prévu sans problème.
Résumé
Cet article a examiné en détail l’utilisation de la liaison de données et du codage clé-valeur dans une application Xamarin.Mac. Tout d’abord, il a examiné l’exposition d’une classe C# à l’aide Objective-C du codage clé-valeur (KVC) et de l’observation de clé-valeur (KVO). Ensuite, il a montré comment utiliser une classe conforme KVO et Data Bind à des éléments d’interface utilisateur dans le Générateur d’interface de Xcode. Enfin, il a montré une liaison de données complexe à l’aide de contrôleurs de tableau et de contrôleurs d’arborescence.
Liens associés
- Hello, Mac
- Contrôles standard
- Vues Table
- Affichages hiérarchiques
- Vues de collection
- Guide de programmation de codage clé-valeur
- Présentation du guide de programmation d’observation des valeurs clés
- Présentation des rubriques de programmation des liaisons Cocoa
- Présentation de la référence sur les liaisons de cacao
- NSCollectionView
- Human Interface Guidelines pour macOS