Привязка данных и кодирование ключей в Xamarin.Mac
В этой статье описывается использование кодирования ключа и наблюдения за ключом, чтобы обеспечить привязку данных к элементам пользовательского интерфейса в построителе интерфейсов Xcode.
Обзор
При работе с C# и .NET в приложении Xamarin.Mac у вас есть доступ к тем же методам кодирования с ключом и привязкой данных, в которых работает Objective-C разработчик и Xcode . Так как Xamarin.Mac интегрируется непосредственно с Xcode, вы можете использовать построитель интерфейсов Xcode для привязки данных с элементами пользовательского интерфейса вместо написания кода.
Используя методы кодирования с ключом и привязки данных в приложении Xamarin.Mac, вы можете значительно уменьшить объем кода, который необходимо написать и поддерживать для заполнения и работы с элементами пользовательского интерфейса. Кроме того, вы можете дополнительно отсогласовать резервные данные (модель данных) с интерфейсного пользовательского интерфейса (model-View-Controller), что упрощает обслуживание, более гибкое проектирование приложений.
В этой статье мы рассмотрим основы работы с кодом ключа и привязкой данных в приложении Xamarin.Mac. Настоятельно рекомендуется сначала ознакомиться со статьей Hello, Mac , в частности в разделах "Введение в Xcode" и "Конструктор интерфейсов" и "Торговых точек" и "Действия ", поскольку рассматриваются основные понятия и методы, которые мы будем использовать в этой статье.
Возможно, вам потребуется ознакомиться с классами И методами C# в Objective-Cразделе документа Xamarin.Mac Internals, а также объяснить Register
Export
и атрибуты, используемые для подключения классов C# к Objective-C объектам и элементам пользовательского интерфейса.
Что такое кодирование ключа-значение
Кодирование ключевого значения (KVC) — это механизм для косвенного доступа к свойствам объекта с помощью ключей (специально отформатированных строк) для идентификации свойств вместо доступа к ним через переменные экземпляра или методы доступа (get/set
). Реализуя средства доступа, соответствующие ключу значения, в приложении Xamarin.Mac, вы получаете доступ к другим функциям macOS (ранее известной как OS X), таким как наблюдение за ключевым значением (KVO), привязка данных, основные данные, привязки Какао и скрипты.
Используя методы кодирования с ключом и привязки данных в приложении Xamarin.Mac, вы можете значительно уменьшить объем кода, который необходимо написать и поддерживать для заполнения и работы с элементами пользовательского интерфейса. Кроме того, вы можете дополнительно отсогласовать резервные данные (модель данных) с интерфейсного пользовательского интерфейса (model-View-Controller), что упрощает обслуживание, более гибкое проектирование приложений.
Например, давайте рассмотрим следующее определение класса соответствующего объекта 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")]
атрибут регистрирует класс и предоставляет его Objective-C. Затем класс должен наследовать от NSObject
(или подкласса, наследуемого от NSObject
), это добавляет несколько базовых методов, которые позволяют классу соответствовать KVC. [Export("Name")]
Затем атрибут предоставляет Name
свойство и определяет значение ключа, которое позже будет использоваться для доступа к свойству с помощью методов KVC и KVO.
Наконец, чтобы иметь возможность быть key-Value Observed изменения значения свойства, метод доступа должен упаковывать изменения в его значение и WillChangeValue
вызовы метода (указывая тот же ключ, что Export
и DidChangeValue
атрибут). Например:
set {
WillChangeValue ("Name");
_name = value;
DidChangeValue ("Name");
}
Этот шаг очень важен для привязки данных в построителе интерфейсов Xcode (как показано далее в этой статье).
Дополнительные сведения см. в руководстве по программированию программирования на основе ключевых значений Apple.
Ключи и пути ключей
Ключ — это строка, определяющая определенное свойство объекта. Как правило, ключ соответствует имени метода доступа в объекте, совместимом с ключом- значением. Ключи должны использовать кодировку ASCII, обычно начинаться с строчной буквы и не содержать пробелы. Таким образом, учитывая приведенный выше пример, Name
будет значение Name
ключа свойства PersonModel
класса. Ключ и имя свойства, которое они предоставляют, не должны совпадать, однако в большинстве случаев они являются одинаковыми.
Путь к ключу — это строка разделенных точками ключей, используемая для указания иерархии свойств объекта для обхода. Свойство первого ключа в последовательности относительно приемника, и каждый последующий ключ вычисляется относительно значения предыдущего свойства. Таким же образом вы используете нотацию точек для обхода объекта и его свойств в классе C#.
Например, если вы расширили PersonModel
класс и добавили Child
свойство:
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 ()
{
}
}
}
Ключ пути к имени ребенка будет self.Child.Name
или просто Child.Name
(в зависимости от того, как используется значение ключа).
Получение значений с помощью кодирования "ключ-значение"
Метод ValueForKey
возвращает значение указанного ключа (как a NSString
), относительно экземпляра класса KVC, получающего запрос. Например, если Person
это экземпляр класса, определенного PersonModel
выше:
// Read value
var name = Person.ValueForKey (new NSString("Name"));
Это возвращает значение Name
свойства для этого экземпляра PersonModel
.
Настройка значений с помощью кодирования "ключ-значение"
Аналогичным образом SetValueForKey
задайте значение для указанного ключа (как a NSString
), относительно экземпляра класса KVC, получающего запрос. Поэтому снова, используя экземпляр PersonModel
класса, как показано ниже:
// Write value
Person.SetValueForKey(new NSString("Jane Doe"), new NSString("Name"));
Изменит значение Name
свойства Jane Doe
на .
Наблюдение за изменениями значений
С помощью наблюдения за ключом (KVO) можно подключить наблюдателя к определенному ключу соответствующего класса KVC и получать уведомления в любое время изменения значения этого ключа (с помощью методов KVC или непосредственного доступа к заданному свойству в коде C#). Например:
// Watch for the name value changing
Person.AddObserver ("Name", NSKeyValueObservingOptions.New, (sender) => {
// Inform caller of selection change
Console.WriteLine("New Name: {0}", Person.Name)
});
Теперь при Name
изменении свойства экземпляра Person
PersonModel
класса новое значение записывается в консоль.
Дополнительные сведения см. в руководстве по программированию на основе ключевых значений Apple.
Привязка данных
В следующих разделах показано, как использовать кодирование ключей и значение ключа для наблюдения за соответствующим классом для привязки данных к элементам пользовательского интерфейса в построителе интерфейсов Xcode вместо чтения и записи значений с помощью кода C#. Таким образом вы отделяете модель данных от представлений, которые используются для их отображения, что делает приложение Xamarin.Mac более гибким и удобным для обслуживания. Вы также значительно уменьшаете объем кода, который должен быть записан.
Определение модели данных
Прежде чем можно привязать элемент пользовательского интерфейса в Interface Builder, необходимо иметь класс соответствия KVC/KVO, определенный в приложении Xamarin.Mac, чтобы выступать в качестве модели данных для привязки. Модель данных предоставляет все данные, которые будут отображаться в пользовательском интерфейсе и получают любые изменения данных, которые пользователь делает в пользовательском интерфейсе при запуске приложения.
Например, если вы написали приложение, управляемое группой сотрудников, можно использовать следующий класс для определения модели данных:
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
}
}
Большинство функций этого класса были рассмотрены в разделе "Что такое кодирование с ключевым значением" выше. Однако давайте рассмотрим несколько конкретных элементов и некоторые дополнения, которые были сделаны, чтобы этот класс действовал как модель данных для контроллеров массивов и контроллеров деревьев (которые мы будем использовать позже для привязки представлений дерева данных, представлений структуры и представлений коллекции).
Во-первых, поскольку сотрудник может быть руководителем, мы использовали NSArray
(в частности, так NSMutableArray
, чтобы значения можно было изменить), чтобы разрешить сотрудникам, которым они удалось присоединиться к ним:
private NSMutableArray _people = new NSMutableArray();
...
[Export("personModelArray")]
public NSArray People {
get { return _people; }
}
Две вещи, которые следует отметить здесь:
- Мы использовали
NSMutableArray
вместо стандартного массива или коллекции C#, так как это требование для привязки данных к элементам управления AppKit, таким как представления таблиц, представления структуры и коллекции. - Мы предоставили массив сотрудников путем приведения его к
NSArray
объекту для привязки данных и изменили его форматированное имя C#, на тот, который ожидает привязка данных,People
в форме {class_name}Array (обратите внимание,personModelArray
что первый символ был сделан нижним регистром).
Далее необходимо добавить некоторые специальные методы имени для поддержки контроллеров массивов и контроллеров деревьев:
[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");
}
Они позволяют контроллерам запрашивать и изменять отображаемые данные. Как и в приведенном NSArray
выше примере, они имеют очень конкретное соглашение об именовании (которое отличается от типичных соглашений об именовании C#):
addObject:
— добавляет объект в массив.insertObject:in{class_name}ArrayAtIndex:
— Где{class_name}
находится имя класса. Этот метод вставляет объект в массив по заданному индексу.removeObjectFrom{class_name}ArrayAtIndex:
— Где{class_name}
находится имя класса. Этот метод удаляет объект в массиве по заданному индексу.set{class_name}Array:
— Где{class_name}
находится имя класса. Этот метод позволяет заменить существующий перенос новым.
В этих методах мы упаковали изменения в WillChangeValue
массив и DidChangeValue
сообщения для соответствия KVO.
Наконец, так как Icon
свойство зависит от значения свойства, изменения isManager
свойства могут не отражаться в Icon
элементах пользовательского isManager
интерфейса привязки данных (во время KVO):
[Export("Icon")]
public NSImage Icon {
get {
if (isManager) {
return NSImage.ImageNamed ("group.png");
} else {
return NSImage.ImageNamed ("user.png");
}
}
}
Чтобы исправить это, мы используем следующий код:
[Export("isManager")]
public bool isManager {
get { return _isManager; }
set {
WillChangeValue ("isManager");
WillChangeValue ("Icon");
_isManager = value;
DidChangeValue ("isManager");
DidChangeValue ("Icon");
}
}
Обратите внимание, что помимо собственного ключа, метод доступа также отправляет WillChangeValue
и DidChangeValue
сообщения для Icon
ключа, isManager
чтобы он также видел изменения.
Мы будем использовать PersonModel
модель данных в остальной части этой статьи.
Простая привязка данных
Определим нашу модель данных, давайте рассмотрим простой пример привязки данных в построителе интерфейсов Xcode. Например, давайте добавим форму в наше приложение Xamarin.Mac, которое можно использовать для изменения PersonModel
указанного выше. Мы добавим несколько текстовых полей и флажок для отображения и редактирования свойств нашей модели.
Сначала добавим новый контроллер представления в файл Main.storyboard в построителе интерфейсов и назовем его классSimpleViewController
:
Затем вернитесь к Visual Studio для Mac, измените файл SimpleViewController.cs (который был автоматически добавлен в наш проект) и предоформьте экземплярPersonModel
, к которому мы будем привязать форму к данным. Добавьте следующий код:
private PersonModel _person = new PersonModel();
...
[Export("Person")]
public PersonModel Person {
get {return _person; }
set {
WillChangeValue ("Person");
_person = value;
DidChangeValue ("Person");
}
}
Затем при загрузке представления создадим экземпляр нашего PersonModel
кода и заполните его следующим кодом:
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;
}
Теперь нам нужно создать форму, дважды щелкните файл Main.storyboard , чтобы открыть его для редактирования в Конструкторе интерфейсов. Макет формы, чтобы выглядеть примерно так:
Чтобы привязать форму к PersonModel
предоставленному ключу Person
, сделайте следующее:
Выберите текстовое поле имени сотрудника и перейдите в инспектор привязок.
Установите флажок "Привязка" и выберите "Простой контроллер представления" в раскрывающемся списке. Затем введите
self.Person.Name
путь к ключу:Выберите поле "Текст оккупации" и проверка поле "Привязка" и выберите "Простой контроллер представления" в раскрывающемся списке. Затем введите
self.Person.Occupation
путь к ключу:Установите флажок "Сотрудник" и проверка поле "Привязка" и выберите "Простой контроллер представления" в раскрывающемся списке. Затем введите
self.Person.isManager
путь к ключу:Выберите поле "Число сотрудников", управляемое текстовое поле и проверка поле "Привязка к" и выберите "Простой контроллер представления" в раскрывающемся списке. Затем введите
self.Person.NumberOfEmployees
путь к ключу:Если сотрудник не является руководителем, мы хотим скрыть количество сотрудников, управляемых меткой и текстовым полем.
Выберите число управляемых меток сотрудников, разверните скрытый откат и проверка поле "Привязка к" и выберите "Простой контроллер представления" в раскрывающемся списке. Затем введите
self.Person.isManager
путь к ключу:Выберите из раскрывающегося
NSNegateBoolean
списка "Преобразователь значений":Это сообщает привязке данных, что метка будет скрыта, если значение
isManager
свойства равноfalse
.Повторите шаги 7 и 8 для числа управляемых текстовых полей сотрудников.
Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.
При запуске приложения значения из Person
свойства автоматически заполняются нашей формой:
Все изменения, внесенные пользователями в форму, будут записаны обратно Person
в свойство в контроллере представления. Например, отмена выбора "Сотрудник" — это менеджер , который обновляет Person
экземпляр нашего PersonModel
приложения, а число управляемых меток сотрудников и текстовое поле скрыты автоматически (с помощью привязки данных):
Привязка данных представления таблицы
Теперь, когда у нас есть основы привязки данных, давайте рассмотрим более сложную задачу привязки данных с помощью контроллера массива и привязки данных к представлению таблицы. Дополнительные сведения о работе с представлениями таблиц см. в документации по представлениям таблиц.
Сначала добавим новый контроллер представления в файл Main.storyboard в построителе интерфейсов и назовем его классTableViewController
:
Затем давайте отредактируем файл TableViewController.cs (который был автоматически добавлен в наш проект) и предоставьте массивNSArray
() PersonModel
классов, к которым мы будем привязывать нашу форму. Добавьте следующий код:
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");
}
Как и в PersonModel
приведенном выше классе в разделе "Определение модели данных", мы предоставили четыре специально именованных открытых метода, чтобы контроллер массива и чтение и запись данных из нашей коллекции PersonModels
.
Затем при загрузке представления необходимо заполнить наш массив этим кодом:
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"));
}
Теперь нам нужно создать представление таблицы, дважды щелкните файл Main.storyboard , чтобы открыть его для редактирования в Конструкторе интерфейсов. Макет таблицы, чтобы выглядеть примерно так:
Необходимо добавить контроллер массива для предоставления привязанных данных к таблице, сделайте следующее:
Перетащите контроллер массива из инспектора библиотеки в редактор интерфейса:
Выберите контроллер массива в иерархии интерфейса и переключитесь на инспектор атрибутов:
Введите
PersonModel
имя класса, нажмите кнопку "Плюс" и добавьте три ключа. Присвойте им имяName
иOccupation
isManager
:Это сообщает контроллеру массива, что он управляет массивом, и какие свойства он должен предоставлять (с помощью ключей).
Перейдите в инспектор привязок и в разделе "Массив контента" выберите "Привязка" и "Контроллер представления таблиц". Введите путь
self.personModelArray
к ключу модели:Это связывает контроллер массива
PersonModels
с массивом, который мы предоставили на контроллере представления.
Теперь необходимо привязать представление таблицы к контроллеру массива, сделайте следующее:
Выберите представление таблицы и инспектор привязки:
В раскрывающемся списке содержимого выберите "Привязка" и "Контроллер массива". Введите
arrangedObjects
поле "Ключ контроллера":Выберите ячейку представления таблицы в столбце Employee. В инспекторе привязок в раскрывающемся списке "Значение" выберите "Привязка к" и "Представление ячеек таблицы". Введите
objectValue.Name
путь к ключу модели:objectValue
является текущимPersonModel
в массиве, управляемым контроллером массива.Выберите ячейку представления таблицы в столбце "Оккупация". В инспекторе привязок в раскрывающемся списке "Значение" выберите "Привязка к" и "Представление ячеек таблицы". Введите
objectValue.Occupation
путь к ключу модели:Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.
Если мы запускаем приложение, таблица будет заполнена нашим массивом PersonModels
:
Привязка данных представления структуры
Привязка данных к представлению структуры очень похожа на привязку к представлению таблицы. Ключевое различие заключается в том, что мы будем использовать контроллер дерева вместо контроллера массива для предоставления привязанных данных к представлению структуры. Дополнительные сведения о работе с представлениями структуры см. в документации по представлениям структуры.
Сначала добавим новый контроллер представления в файл Main.storyboard в построителе интерфейсов и назовем его классOutlineViewController
:
Затем давайте отредактируем файл OutlineViewController.cs (который был автоматически добавлен в наш проект) и предоставьте массивNSArray
() PersonModel
классов, к которым мы будем привязывать нашу форму. Добавьте следующий код:
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");
}
Как и в PersonModel
приведенном выше классе в разделе "Определение модели данных", мы предоставили четыре специально именованных открытых метода, чтобы контроллер дерева и чтение и запись данных из нашей коллекции PersonModels
.
Затем при загрузке представления необходимо заполнить наш массив этим кодом:
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);
}
Теперь нам нужно создать представление структуры, дважды щелкните файл Main.storyboard , чтобы открыть его для редактирования в Конструкторе интерфейсов. Макет таблицы, чтобы выглядеть примерно так:
Необходимо добавить контроллер дерева для предоставления привязанных данных в структуру, сделайте следующее:
Перетащите контроллер дерева из инспектора библиотеки в редактор интерфейса:
Выберите контроллер дерева в иерархии интерфейса и переключитесь на инспектор атрибутов:
Введите
PersonModel
имя класса, нажмите кнопку "Плюс" и добавьте три ключа. Присвойте им имяName
иOccupation
isManager
:Это сообщает контроллеру дерева, что он управляет массивом, и какие свойства он должен предоставлять (с помощью ключей).
В разделе "Контроллер дерева" введите "Дочерние", введите
NumberOfEmployees
personModelArray
в поле "Число" и введитеisEmployee
в поле "Лист":Это указывает контроллеру дерева, где найти все дочерние узлы, сколько дочерних узлов есть и если текущий узел имеет дочерние узлы.
Перейдите в инспектор привязок и в разделе "Массив контента" выберите "Привязка" и "Владелец файла". Введите путь
self.personModelArray
к ключу модели:Это связывает контроллер дерева с массивом
PersonModels
, который мы предоставили на контроллере представления.
Теперь необходимо привязать представление структуры к контроллеру дерева, сделайте следующее:
Выберите представление структуры и в инспекторе привязки выберите:
В раскрывающемся списке "Содержимое представления структуры" выберите "Привязка" и "Контроллер дерева". Введите
arrangedObjects
поле "Ключ контроллера":Выберите ячейку представления таблицы в столбце Employee. В инспекторе привязок в раскрывающемся списке "Значение" выберите "Привязка к" и "Представление ячеек таблицы". Введите
objectValue.Name
путь к ключу модели:objectValue
— текущийPersonModel
в массиве, управляемый контроллером дерева.Выберите ячейку представления таблицы в столбце "Оккупация". В инспекторе привязок в раскрывающемся списке "Значение" выберите "Привязка к" и "Представление ячеек таблицы". Введите
objectValue.Occupation
путь к ключу модели:Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.
Если мы запускаем приложение, структура будет заполнена нашим массивом PersonModels
:
Привязка данных представления коллекции
Привязка данных с представлением коллекции очень похожа на привязку с представлением таблицы, так как контроллер массива используется для предоставления данных для коллекции. Так как представление коллекции не имеет предустановленного формата отображения, для получения отзывов о взаимодействии с пользователем и отслеживания выбора пользователей требуется дополнительная работа.
Внимание
Из-за проблемы в Xcode 7 и macOS 10.11 (и больше), представления коллекции не могут использоваться внутри файлов раскадровки (раскадровки). В результате необходимо продолжать использовать XIB-файлы для определения представлений коллекции для приложений Xamarin.Mac. Дополнительные сведения см. в документации по представлениям коллекции.
Отладка собственных сбоев
Ошибка при привязках данных может привести к сбою машинного кода в неуправляемом коде и привести к сбою приложения Xamarin.Mac с ошибкой SIGABRT
:
Обычно во время привязки данных во время привязки данных возникают четыре основных причины сбоя в машинном коде:
- Модель данных не наследует от
NSObject
подклассаNSObject
. - Свойство не было предоставлено Objective-C для использования атрибута
[Export("key-name")]
. - Вы не заключили изменения в значение метода доступа и
WillChangeValue
вызовы метода (указывая тот же ключ, чтоExport
иDidChangeValue
атрибут). - У вас есть неправильный или неправильный ключ в инспекторе привязки в построителе интерфейсов.
Декодирование сбоя
Давайте создадим собственный сбой в привязке данных, чтобы мы могли показать, как найти и исправить его. В построителе интерфейсов мы изменим привязку первой метки в примере представления коллекции на Name
Title
:
Давайте сохраните изменение, переключимся на Visual Studio для Mac, чтобы синхронизироваться с Xcode и запустить наше приложение. При отображении представления коллекции приложение мгновенно завершает работу с SIGABRT
ошибкой (как показано в выходных данных приложения в Visual Studio для Mac), так как PersonModel
свойство с ключом Title
не предоставляется:
Если прокручиваться до самой верхней части ошибки в выходных данных приложения, мы видим ключ для решения проблемы:
Эта строка говорит нам, что ключ Title
не существует в объекте, к которому мы привязываются. Если изменить привязку обратно Name
в конструктор интерфейсов, сохранить, синхронизировать, перестроить и запустить, приложение будет работать должным образом без проблем.
Итоги
В этой статье подробно описано, как работать с привязкой данных и кодом ключа в приложении Xamarin.Mac. Во-первых, он рассмотрел возможность предоставления класса Objective-C C# использованию кода ключевого значения (KVC) и наблюдения за ключом (KVO). Далее он показал, как использовать класс, совместимый с KVO, и Привязка данных к элементам пользовательского интерфейса в построителе интерфейсов Xcode. Наконец, она показала сложную привязку данных с помощью контроллеров массива и контроллеров деревьев.
Связанные ссылки
- Привет, Mac
- Стандартные элементы управления
- Представления таблиц
- Представления структуры
- Представления коллекции
- Руководство по программированию программирования на основе ключевых значений
- Общие сведения о руководстве по программированию на основе ключевых значений
- Общие сведения о программировании привязок Какао
- Общие сведения о справочнике по привязкам Какао
- NSCollectionView
- Рекомендации по созданию пользовательских интерфейсов в macOS