Xamarin. Mac でのデータバインディングとキー値のコーディングData binding and key-value coding in Xamarin.Mac

この記事では、キーと値のコードを使用して、Xcode の Interface Builder の UI 要素にデータをバインドできるようにするためのキーと値の監視について説明します。This article covers using key-value coding and key-value observing to allow for data binding to UI elements in Xcode's Interface Builder.

概要Overview

Xamarin. Mac アプリケーションで C# と .NET を使用する場合、 Xcode と で作業する開発者が行う のと同じ キー値のコーディングとデータバインディングの手法にアクセスできます。When working with C# and .NET in a Xamarin.Mac application, you have access to the same key-value coding and data binding techniques that a developer working in Objective-C and Xcode does. Xcode は直接統合されているため、コードを記述する代わりに、Xcode の Interface Builder を使用して、UI 要素とのデータバインドを行うことができます。Because Xamarin.Mac integrates directly with Xcode, you can use Xcode's Interface Builder to Data Bind with UI elements instead of writing code.

UI 要素を設定して操作するために、Xamarin. Mac アプリケーションでキー値のコードとデータバインディングの手法を使用することにより、記述して維持する必要があるコードの量を大幅に減らすことができます。By using key-value coding and data binding techniques in your Xamarin.Mac application, you can greatly decrease the amount of code that you have to write and maintain to populate and work with UI elements. また、フロントエンドのユーザーインターフェイス (モデルビューコントローラー) からバッキングデータ (データモデル) をさらに分離することもできます。これにより、管理が容易になり、アプリケーションの設計をより柔軟に行うことができます。You also have the benefit of further decoupling your backing data (Data Model) from your front end User Interface (Model-View-Controller), leading to easier to maintain, more flexible application design.

実行中のアプリの例An example of the running app

この記事では、Xamarin. Mac アプリケーションでのキー値のコーディングとデータバインディングの操作の基本について説明します。In this article, we'll cover the basics of working with key-value coding and data binding in a Xamarin.Mac application. この記事で使用する主要な概念と手法について説明しているように、最初に Hello, Mac の記事「 Xcode と Interface Builder の概要 」と「 アウトレットとアクション 」セクションをご覧になることを強くお勧めします。It is highly suggested that you work through the Hello, Mac article first, specifically the Introduction to Xcode and Interface Builder and Outlets and Actions sections, as it covers key concepts and techniques that we'll be using in this article.

ここでは、 Xamarin の内部ドキュメントのc# クラス/メソッドを目的の c に公開する方法について説明します Register Export 。 c# クラスを目的の c オブジェクトと UI 要素に接続するために使用される属性と属性についても説明します。You may want to take a look at the Exposing C# classes / methods to Objective-C section of the Xamarin.Mac Internals document as well, it explains the Register and Export attributes used to wire up your C# classes to Objective-C objects and UI elements.

キー値のコーディングとはWhat is key-value coding

キー値のコーディング (KVC) は、オブジェクトのプロパティに間接的にアクセスするためのメカニズムです。キー (特殊な書式設定文字列) を使用して、インスタンス変数またはアクセサーメソッド () を使用してアクセスするのではなく、プロパティを識別し get/set ます。Key-value coding (KVC) is a mechanism for accessing an object’s properties indirectly, using keys (specially formatted strings) to identify properties instead of accessing them through instance variables or accessor methods (get/set). Xamarin. Mac アプリケーションでキー値のコーディングに準拠したアクセサーを実装することによって、キー値の観察 (KVO)、データバインディング、コアデータ、Cocoa バインド、および scriptability 可能な他の macOS (旧 OS X) 機能にアクセスできるようになります。By implementing key-value coding compliant accessors in your Xamarin.Mac application, you gain access to other macOS (formerly known as OS X) features such as key-value observing (KVO), data binding, Core Data, Cocoa bindings, and scriptability.

UI 要素を設定して操作するために、Xamarin. Mac アプリケーションでキー値のコードとデータバインディングの手法を使用することにより、記述して維持する必要があるコードの量を大幅に減らすことができます。By using key-value coding and data binding techniques in your Xamarin.Mac application, you can greatly decrease the amount of code that you have to write and maintain to populate and work with UI elements. また、フロントエンドのユーザーインターフェイス (モデルビューコントローラー) からバッキングデータ (データモデル) をさらに分離することもできます。これにより、管理が容易になり、アプリケーションの設計をより柔軟に行うことができます。You also have the benefit of further decoupling your backing data (Data Model) from your front end User Interface (Model-View-Controller), leading to easier to maintain, more flexible application design.

たとえば、KVC 準拠オブジェクトの次のクラス定義を見てみましょう。For example, let's look at the following class definition of a KVC compliant object:

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")] 属性はクラスを登録し、それを目的の C に公開します。First, the [Register("PersonModel")] attribute registers the class and exposes it to Objective-C. 次に、クラスは、 NSObject (またはから継承するサブクラス) から継承する必要があり NSObject ます。これにより、クラスを kvc 準拠にすることができるいくつかの基本メソッドが追加されます。Then, the class needs to inherit from NSObject (or a subclass that inherits from NSObject), this adds several base method that allow to the class to be KVC compliant. 次に、 [Export("Name")] 属性はプロパティを公開 Name し、後で kvc および kvc 手法を使用してプロパティにアクセスするために使用されるキー値を定義します。Next, the [Export("Name")] attribute exposes the Name property and defines the Key value that will later be used to access the property through KVC and KVO techniques.

最後に、プロパティの値が変更されたことを Key-Value に確認できるようにするには、アクセサーがの値に対する変更を WillChangeValueDidChangeValue メソッドの呼び出し (属性と同じキーを指定) でラップする必要があり Export ます。Finally, to be able to be Key-Value Observed changes to the property's value, the accessor must wrap changes to its value in WillChangeValue and DidChangeValue method calls (specifying the same Key as the Export attribute). 例:For example:

set {
    WillChangeValue ("Name");
    _name = value;
    DidChangeValue ("Name");
}

この手順は、この記事で後ほど説明するように、Xcode の Interface Builder でのデータバインディングでは 非常に 重要です。This step is very important for data binding in Xcode's Interface Builder (as we will see later in this article).

詳細については、「Apple の キー値コードプログラミングガイド」を参照してください。For more information, please see Apple's Key-Value Coding Programming Guide.

キーとキーのパスKeys and key paths

キー は、オブジェクトの特定のプロパティを識別する文字列です。A Key is a string that identifies a specific property of an object. 通常、キーは、キー値のコーディングに準拠したオブジェクトのアクセサーメソッドの名前に対応します。Typically, a key corresponds to the name of an accessor method in a key-value coding compliant object. キーは ASCII エンコードを使用する必要があり、通常は小文字で始まり、空白を含めることはできません。Keys must use ASCII encoding, usually begin with a lowercase letter, and may not contain whitespace. 上記の例では、は Name クラスのプロパティのキー値になり Name PersonModel ます。So given the example above, Name would be a Key Value of Name property of the PersonModel class. 公開するプロパティのキーと名前は同じである必要はありませんが、ほとんどの場合は同じです。The Key and the name of the property that they expose don't have to be the same, however in most cases they are.

キーパス は、走査するオブジェクトプロパティの階層を指定するために使用される、ドットで区切られたキーの文字列です。A Key Path is a string of dot separated Keys used to specify a hierarchy of object properties to traverse. シーケンス内の最初のキーのプロパティは受信側に対して相対的であり、後続の各キーは、前のプロパティの値に対して相対的に評価されます。The property of the first key in the sequence is relative to the receiver, and each subsequent key is evaluated relative to the value of the previous property. 同様に、ドット表記を使用して、C# クラスのオブジェクトとそのプロパティを走査します。In the same way you use dot notation to traverse an object and its properties in a C# class.

たとえば、クラスを展開し、プロパティを追加した場合は、次のように PersonModel Child なります。For example, if you expanded the PersonModel class and added Child property:

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 (キー値がどのように使用されていたかに基づいて) 単純です。The Key Path to the child's name would be self.Child.Name or simply Child.Name (based on how the Key Value was being used).

キー値のコードを使用した値の取得Getting values using key-value coding

メソッドは、 ValueForKey NSString 要求を受け取る kvc クラスのインスタンスに対して、指定されたキーの値を (として) 返します。The ValueForKey method returns the value for the specified Key (as a NSString), relative to the instance of the KVC class receiving the request. たとえば、 Person が上で定義されたクラスのインスタンスである場合は、次のようになり PersonModel ます。For example, if Person is an instance of the PersonModel class defined above:

// Read value
var name = Person.ValueForKey (new NSString("Name"));

これにより、 Name のインスタンスのプロパティの値が返さ PersonModel れます。This would return the value of the Name property for that instance of PersonModel.

キー値のコードを使用した値の設定Setting values using key-value coding

同様に、は、 SetValueForKey NSString 要求を受け取る kvc クラスのインスタンスを基準として、指定されたキーの値をとして設定します。Similarly, the SetValueForKey set the value for the specified Key (as a NSString), relative to the instance of the KVC class receiving the request. 次に示すように、クラスのインスタンスを使用し PersonModel ます。So again, using an instance of the PersonModel class, as shown below:

// Write value
Person.SetValueForKey(new NSString("Jane Doe"), new NSString("Name"));

は、プロパティの値 Name をに変更し Jane Doe ます。Would change the value of the Name property to Jane Doe.

値の変更の観察Observing value changes

キー値の観測 (KVO) を使用すると、KVO 準拠クラスの特定のキーにオブザーバーをアタッチし、そのキーの値が変更されたときに通知を受け取ることができます (KVO 技法を使用するか、C# コードの特定のプロパティに直接アクセスします)。Using key-value observing (KVO), you can attach an observer to a specific Key of a KVC compliant class and be notified any time the value for that Key is modified (either using KVC techniques or directly accessing the given property in C# code). 例:For example:

// 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 新しい値がコンソールに書き込まれます。Now, any time the Name property of the Person instance of the PersonModel class is modified, the new value is written out to the console.

詳細については、Apple の Key-Value 監視プログラミングガイドの概要を参照してください。For more information, please see Apple's Introduction to Key-Value Observing Programming Guide.

データ バインディングData binding

次のセクションでは、C# コードを使用して値の読み取りと書き込みを行うのではなく、キー値のコードとキー値の監視に準拠したクラスを使用して、Xcode の Interface Builder の UI 要素にデータをバインドする方法について説明します。The following sections will show how you can use a key-value coding and key-value observing compliant class to bind data to UI elements in Xcode's Interface Builder, instead of reading and writing values using C# code. この方法では、 データモデル を表示するために使用されているビューとは別にして、Xamarin. Mac アプリケーションの柔軟性と保守性を高めることができます。In this way you separate your Data Model from the views that are used to display them, making the Xamarin.Mac application more flexible and easier to maintain. また、記述する必要があるコードの量を大幅に減らすことができます。You also greatly decrease the amount of code that has to be written.

データモデルの定義Defining your data model

Interface Builder で UI 要素をデータバインドするには、その前に、バインドの データモデル として機能するように、Xamarin. Mac アプリケーションで kvc/kvc に準拠したクラスが定義されている必要があります。Before you can Data Bind a UI element in Interface Builder, you must have a KVC/KVO compliant class defined in your Xamarin.Mac application to act as the Data Model for the binding. データモデルは、ユーザーインターフェイスに表示されるすべてのデータを提供し、アプリケーションの実行中にユーザーが UI で行ったデータへの変更を受け取ります。The Data Model provides all of the data that will be displayed in the User Interface and receives any modifications to the data that the user makes in the UI while running the application.

たとえば、従業員のグループを管理するアプリケーションを作成する場合は、次のクラスを使用してデータモデルを定義できます。For example, if you were writing an application that managed a group of employees, you could use the following class to define the Data Model:

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

このクラスのほとんどの機能については、上の「 キー値のコーディングとは 」セクションで説明しました。Most of the features of this class were covered in the What is key-value coding section above. ただし、このクラスが 配列コントローラーツリーコントローラー のデータモデルとして機能できるようにするために加えられたいくつかの特定の要素といくつかの追加について説明します (後でデータバインド ツリービューアウトラインビュー 、および コレクションビュー に使用します)。However, let's look at a few specific elements and some additions that were made to allow this class to act as a Data Model for Array Controllers and Tree Controllers (which we'll be using later to Data bind Tree Views, Outline Views and Collection Views).

1つ目の理由は、従業員が上司である可能性があるため、 NSArray (具体的には、値を変更できるように) を使用して、自分が管理している従業員を関連付けることができるようにしました NSMutableArrayFirst, because an employee might be a manager, we've used a NSArray (specifically a NSMutableArray so the values can be modified) to allow the employees that they managed to be attached to them:

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

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

次の2つの点に注意してください。Two things to note here:

  1. NSMutableArray標準的な C# の配列またはコレクションではなく、を使用しています。これは、テーブルビューアウトラインビューコレクション などの appkit コントロールにデータをバインドするための要件であるためです。We used a NSMutableArray instead of a standard C# array or collection since this is a requirement to Data Bind to AppKit controls such as Table Views, Outline Views and Collections.
  2. 従業員の配列は、データバインディングのためににキャストし、 NSArray C# の書式設定された名前を People データバインディングが想定するものに変更して、 personModelArray {class_name} 配列 (最初の文字が小文字になっていることに注意してください) に変更しました。We exposed the array of employees by casting it to a NSArray for data binding purposes and changed its C# formatted name, People, to one that data binding expects, personModelArray in the form {class_name}Array (note that the first character has been made lower case).

次に、 配列コントローラーツリーコントローラー をサポートするために、特別な名前のパブリックメソッドをいくつか追加する必要があります。Next, we need to add some specially name public methods to support Array Controllers and Tree Controllers:

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

これにより、コントローラーは、表示されるデータを要求および変更できます。These allow the controllers to request and modify the data that they display. 上記のように公開されているのと同様に、 NSArray これらは非常に具体的な名前付け規則を持ちます (一般的な C# の名前付け規則とは異なります)。Like the exposed NSArray above, these have a very specific naming convention (that differs from the typical C# naming conventions):

  • addObject: -オブジェクトを配列に追加します。addObject: - Adds an object to the array.
  • insertObject:in{class_name}ArrayAtIndex: - {class_name} はクラスの名前です。insertObject:in{class_name}ArrayAtIndex: - Where {class_name} is the name of your class. このメソッドは、指定されたインデックスの位置にあるオブジェクトを配列に挿入します。This method inserts an object into the array at a given index.
  • removeObjectFrom{class_name}ArrayAtIndex: - {class_name} はクラスの名前です。removeObjectFrom{class_name}ArrayAtIndex: - Where {class_name} is the name of your class. このメソッドは、配列内の指定したインデックス位置にあるオブジェクトを削除します。This method removes the object in the array at a given index.
  • set{class_name}Array: - {class_name} はクラスの名前です。set{class_name}Array: - Where {class_name} is the name of your class. このメソッドを使用すると、既存のキャリーを新しいものに置き換えることができます。This method allows you to replace the existing carry with a new one.

これらのメソッドの内部では、の配列に対する変更 WillChangeValueDidChangeValue kvo 準拠のメッセージをラップしています。Inside of these methods, we've wrapped changes to the array in WillChangeValue and DidChangeValue messages for KVO compliance.

最後に、プロパティは Icon プロパティの値に依存しているため、 isManager プロパティへの変更は isManager 、データバインドされた Icon UI 要素 (kvo 中) には反映されない可能性があります。Finally, since the Icon property relies on the value of the isManager property, changes to the isManager property might not be reflected in the Icon for Data Bound UI elements (during KVO):

[Export("Icon")]
public NSImage Icon {
    get {
        if (isManager) {
            return NSImage.ImageNamed ("group.png");
        } else {
            return NSImage.ImageNamed ("user.png");
        }
    }
}

これを修正するには、次のコードを使用します。To correct that, we use the following code:

[Export("isManager")]
public bool isManager {
    get { return _isManager; }
    set {
        WillChangeValue ("isManager");
        WillChangeValue ("Icon");
        _isManager = value;
        DidChangeValue ("isManager");
        DidChangeValue ("Icon");
    }
}

独自のキーに加えて、 isManager アクセサーもキーのメッセージとメッセージを送信するので、変更も表示されることに注意して WillChangeValue DidChangeValue Icon ください。Note that in addition to its own Key, the isManager accessor is also sending the WillChangeValue and DidChangeValue messages for the Icon Key so it will see the change as well.

PersonModelこの記事の残りの部分では、このデータモデルを使用します。We'll be using the PersonModel Data Model throughout the rest of this article.

単純データ バインディングSimple data binding

データモデルを定義したので、Xcode の Interface Builder でのデータバインディングの簡単な例を見てみましょう。With our Data Model defined, let's look at a simple example of data binding in Xcode's Interface Builder. たとえば、前に定義したを編集するために使用できるフォームを Xamarin. Mac アプリケーションに追加してみましょう。 PersonModelFor example, let's add a form to our Xamarin.Mac application that can be used to edit the PersonModel that we defined above. いくつかのテキストフィールドと、モデルのプロパティを表示および編集するためのチェックボックスを追加します。We'll add a few Text Fields and a Check Box to display and edit properties of our model.

まず、Interface Builder の メインのストーリーボード ファイルに新しい ビューコントローラー を追加し、そのクラスにという名前を指定し SimpleViewController ます。First, let's add a new View Controller to our Main.storyboard file in Interface Builder and name its class SimpleViewController:

SimpleViewController という名前のクラスを使用して、新しいビューコントローラーを追加します。Adding a new view controller with a class named SimpleViewController.

次に、Visual Studio for Mac に戻り、(プロジェクトに自動的に追加された) SimpleViewController.cs ファイルを編集して、フォームのデータバインド先となるのインスタンスを公開し PersonModel ます。Next, return to Visual Studio for Mac, edit the SimpleViewController.cs file (that was automatically added to our project) and expose an instance of the PersonModel that we will be data binding our form to. 次のコードを追加します。Add the following code:

private PersonModel _person = new PersonModel();
...

[Export("Person")]
public PersonModel Person {
    get {return _person; }
    set {
        WillChangeValue ("Person");
        _person = value;
        DidChangeValue ("Person");
    }
}

次に、ビューが読み込まれたら、のインスタンスを作成し、次の PersonModel コードを入力します。Next when the View is loaded, let's create an instance of our PersonModel and populate it with this 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;

}

次に、フォームを作成し、 メインのストーリーボード ファイルをダブルクリックして、Interface Builder で編集できるようにします。Now we need to create our form, double-click the Main.storyboard file to open it for editing in Interface Builder. 次のようにフォームをレイアウトします。Layout the form to look something like the following:

Xcode でストーリーボードを編集するEditing the storyboard in Xcode

このキーを使用して公開したにフォームをデータバインドするには、 PersonModel Person 次の手順を実行します。To Data Bind the form to the PersonModel that we exposed via the Person Key, do the following:

  1. [ Employee Name ] テキストフィールドを選択し、[ バインド] インスペクター に切り替えます。Select the Employee Name Text Field and switch to the Bindings Inspector.

  2. [ バインド先 ] ボックスをオンにし、ドロップダウンから [ 簡易ビューコントローラー ] を選択します。Check the Bind to box and select Simple View Controller from the dropdown. self.Person.Name に、 キーのパス を入力します。Next enter self.Person.Name for the Key Path:

    キーのパスとして、自己ドット名を入力します。Entering self dot person dot name for the Key Path.

  3. [ 職業 ] テキストフィールドを選択し、[ バインド先 ] ボックスをオンにして、ドロップダウンから [ 簡易ビューコントローラー ] を選択します。Select the Occupation Text Field and check the Bind to box and select Simple View Controller from the dropdown. self.Person.Occupation に、 キーのパス を入力します。Next enter self.Person.Occupation for the Key Path:

    キーのパスに対して自己ドットの職業を入力します。Entering self dot Person dot Occupation for the Key Path.

  4. [ 従業員はマネージャーで ある] チェックボックスをオンにし、[ バインド先 ] チェックボックスをオンにして、ドロップダウンから [ 簡易ビューコントローラー ] を選択します。Select the Employee is a Manager Checkbox and check the Bind to box and select Simple View Controller from the dropdown. self.Person.isManager に、 キーのパス を入力します。Next enter self.Person.isManager for the Key Path:

    キーのパスとして「self dot Person dot isManager」と入力します。Entering self dot Person dot isManager for the Key Path.

  5. [ Number Of Employees Managed Text] フィールドを選択し、[ バインド先 ] ボックスをオンにして、ドロップダウンから [ 簡易ビューコントローラー ] を選択します。Select the Number of Employees Managed Text Field and check the Bind to box and select Simple View Controller from the dropdown. self.Person.NumberOfEmployees に、 キーのパス を入力します。Next enter self.Person.NumberOfEmployees for the Key Path:

    キーのパスとして、ユーザーにドットを入力します。Entering self dot Person dot NumberOfEmployees for the Key Path.

  6. 従業員がマネージャーでない場合は、Employees 管理対象ラベルとテキストフィールドの数を非表示にします。If the employee is not a manager, we want to hide the Number of Employees Managed Label and Text Field.

  7. [ Number Of Employees ] \ (従業員管理 ) ラベルを選択し、 非表示 の turndown を展開して [ バインド先 ] ボックスをオンにし、ドロップダウンから [ 簡易ビューコントローラー ] を選択します。Select the Number of Employees Managed Label, expand the Hidden turndown and check the Bind to box and select Simple View Controller from the dropdown. self.Person.isManager に、 キーのパス を入力します。Next enter self.Person.isManager for the Key Path:

    管理者以外のユーザーのキーパスに対して、self ドットのユーザードット isManager を入力します。Entering self dot Person dot isManager for the Key Path for non-managers.

  8. [ NSNegateBoolean 値トランスフォーマー ] ドロップダウンから次のように選択します。Select NSNegateBoolean from the Value Transformer dropdown:

    NSNegateBoolean キー変換の選択Selecting the NSNegateBoolean key transformation

  9. これにより、プロパティの値がの場合にラベルが非表示になることがデータバインディングに伝えられ isManager false ます。This tells data binding that the label will be hidden if the value of the isManager property is false.

  10. [ 従業員の管理対象の テキスト] フィールドに対して、手順 7. および 8. を繰り返します。Repeat steps 7 and 8 for the Number of Employees Managed Text Field.

  11. 変更を保存し Visual Studio for Mac に戻り、Xcode と同期します。Save your changes and return to Visual Studio for Mac to sync with Xcode.

アプリケーションを実行すると、プロパティの値が Person 自動的に設定されます。If you run the application, the values from the Person property will automatically populate our form:

自動入力されたフォームを表示するShowing an auto-populated form

ユーザーがフォームに対して行った変更は、ビューコントローラーのプロパティに書き戻され Person ます。Any changes that the users makes to the form will be written back to the Person property in the View Controller. たとえば、Employee をオフにすると、 マネージャーに よってのインスタンスが更新され、[ Person PersonModel 管理されているラベル] と [テキスト] フィールド の数 は、データバインディングによって自動的に非表示になります。For example, unselecting Employee is a Manager updates the Person instance of our PersonModel and the Number of Employees Managed Label and Text Field are hidden automatically (via data binding):

管理者以外の従業員の数を非表示にするHiding the number of employees for non-managers

テーブルビューのデータバインドTable view data binding

データバインディングの基本を説明したので、次は、 配列コントローラー とテーブルビューへのデータバインディングを使用して、より複雑なデータバインディングタスクを見てみましょう。Now that we have the basics of data binding out of the way, let's look at a more complex data binding task by using an Array Controller and data binding to a Table View. テーブルビューの操作の詳細については、 テーブルビュー のドキュメントを参照してください。For more information on working with Table Views, please see our Table Views documentation.

まず、Interface Builder の メインのストーリーボード ファイルに新しい ビューコントローラー を追加し、そのクラスにという名前を指定し TableViewController ます。First, let's add a new View Controller to our Main.storyboard file in Interface Builder and name its class TableViewController:

TableViewController という名前のクラスを使用して、新しいビューコントローラーを追加します。Adding a new view controller with a class named TableViewController.

次に、 TableViewController.cs ファイルを編集して (プロジェクトに自動的に追加されていた)、 NSArray PersonModel フォームをデータバインドするクラスの配列 () を公開します。Next, let's edit the TableViewController.cs file (that was automatically added to our project) and expose an array (NSArray) of PersonModel classes that we will be data binding our form to. 次のコードを追加します。Add the following code:

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前の「データモデルを定義する」セクションで説明したクラスと同様に、配列コントローラーとのコレクションからデータの読み取りと書き込みを行うために、4つの特別な名前のパブリックメソッドを公開しました PersonModelsJust like we did on the PersonModel class above in the Defining your Data Model section, we've exposed four specially named public methods so that the Array Controller and read and write data from our collection of PersonModels.

次に、ビューが読み込まれたら、次のコードを使用して配列を設定する必要があります。Next when the View is loaded, we need to populate our array with this 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"));

}

ここで、テーブルビューを作成し、 メインのストーリーボード ファイルをダブルクリックして、Interface Builder で編集するために開きます。Now we need to create our Table View, double-click the Main.storyboard file to open it for editing in Interface Builder. テーブルを次のようにレイアウトします。Layout the table to look something like the following:

新しいテーブルビューをレイアウトするLaying out a new table view

テーブルにバインドされたデータを提供する 配列コントローラー を追加する必要があります。次の手順を実行します。We need to add an Array Controller to provide bound data to our table, do the following:

  1. ライブラリインスペクター から インターフェイスエディター配列コントローラー をドラッグします。Drag an Array Controller from the Library Inspector onto the Interface Editor:

    ライブラリからの配列コントローラーの選択Selecting an Array Controller from the Library

  2. インターフェイス階層 で [配列コントローラー ] を選択し、属性インスペクター に切り替えます。Select Array Controller in the Interface Hierarchy and switch to the Attribute Inspector:

    属性インスペクターの選択Selecting the Attributes Inspector

  3. クラス名として「」と入力し、 PersonModel プラス ボタンをクリックして、3つのキーを追加します。Enter PersonModel for the Class Name, click the Plus button and add three Keys. 名前 Name を、次のように指定 OccupationisManager ます。Name them Name, Occupation and isManager:

    必要なキーパスをオブジェクトコントローラーに追加しています。Adding the required key paths to the Object Controller.

  4. これにより、配列がどのように管理しているか、およびキーによって公開する必要があるプロパティが配列コントローラーに伝えられます。This tells the Array Controller what it is managing an array of, and which properties it should expose (via Keys).

  5. バインドインスペクター に切り替え、[コンテンツ配列] で [バインド先] と [テーブルビューコントローラー] を選択します。Switch to the Bindings Inspector and under Content Array select Bind to and Table View Controller. モデルキーのパス を入力してください self.personModelArray :Enter a Model Key Path of self.personModelArray:

    キーのパスを入力するEntering a key path

  6. これにより、ビューコントローラーで公開されたの配列に配列コントローラーが結び付けられ PersonModels ます。This ties the Array Controller to the array of PersonModels that we exposed on our View Controller.

ここで、テーブルビューを配列コントローラーにバインドする必要があります。次の手順を実行します。Now we need to bind our Table View to the Array Controller, do the following:

  1. テーブルビューと バインドインスペクター を選択します。Select the Table View and the Binding Inspector:

    テーブルビューとバインドインスペクターを選択します。Selecting the Table View and Binding Inspector.

  2. テーブルの 内容 turndown の下で、[ Bind To and Array Controller] を選択します。Under the Table Contents turndown, select Bind to and Array Controller. arrangedObjects[コントローラーキー ] フィールドに「」と入力します。Enter arrangedObjects for the Controller Key field:

    コントローラーキーの定義Defining the controller key

  3. [ Employee ] 列の下にある テーブルビューセル を選択します。Select the Table View Cell under the Employee column. Turndown の の下にある [バインド] インスペクター で、[テーブルセルビュー****にバインド] を選択します。In the Bindings Inspector under the Value turndown, select Bind to and Table Cell View. objectValue.Nameモデルキーのパス として「」と入力します。Enter objectValue.Name for the Model Key Path:

    Employee 列のモデルキーのパスを設定します。Setting the model key path for the Employee column.

  4. objectValue は、配列 PersonModel コントローラーによって管理されている配列内の現在のです。objectValue is the current PersonModel in the array being managed by the Array Controller.

  5. [職業] 列の下にある [テーブルビュー] セル を選択します。Select the Table View Cell under the Occupation column. Turndown の の下にある [バインド] インスペクター で、[テーブルセルビュー****にバインド] を選択します。In the Bindings Inspector under the Value turndown, select Bind to and Table Cell View. objectValue.Occupationモデルキーのパス として「」と入力します。Enter objectValue.Occupation for the Model Key Path:

    職業列のモデルキーのパスを設定しています。Setting the model key path for the Occupation column.

  6. 変更を保存し Visual Studio for Mac に戻り、Xcode と同期します。Save your changes and return to Visual Studio for Mac to sync with Xcode.

アプリケーションを実行すると、テーブルに次の配列が格納され PersonModels ます。If we run the application, the table will be populated with our array of PersonModels:

アプリケーションを実行して、個人モデルの配列を設定します。Running the application, which populates the array of PersonModels.

データバインディングのアウトラインビューOutline view data binding

アウトラインビューに対するデータバインディングは、テーブルビューに対するバインドとよく似ています。data binding against an Outline View is very similar to binding against a Table View. 主な違いは、配列コントローラー ではなく ツリーコントローラー を使用して、バインドされたデータをアウトラインビューに提供することです。The key difference is that we'll be using a Tree Controller instead of an Array Controller to provide the bound data to the Outline View. アウトラインビューの操作の詳細については、 アウトラインビュー のドキュメントを参照してください。For more information on working with Outline Views, please see our Outline Views documentation.

まず、Interface Builder の メインのストーリーボード ファイルに新しい ビューコントローラー を追加し、そのクラスにという名前を指定し OutlineViewController ます。First, let's add a new View Controller to our Main.storyboard file in Interface Builder and name its class OutlineViewController:

OutlineViewController という名前のクラスを使用して、新しいビューコントローラーを追加します。Adding a new view controller with a class named OutlineViewController.

次に、 OutlineViewController.cs ファイルを編集して (プロジェクトに自動的に追加されていた)、 NSArray PersonModel フォームをデータバインドするクラスの配列 () を公開します。Next, let's edit the OutlineViewController.cs file (that was automatically added to our project) and expose an array (NSArray) of PersonModel classes that we will be data binding our form to. 次のコードを追加します。Add the following code:

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前の「データモデルの定義」セクションで説明したクラスと同様に、4つの特別な名前のパブリックメソッドを公開しました。これにより、ツリーコントローラーとのコレクションからデータの読み取りと書き込みを行うことが PersonModels できます。Just like we did on the PersonModel class above in the Defining your Data Model section, we've exposed four specially named public methods so that the Tree Controller and read and write data from our collection of PersonModels.

次に、ビューが読み込まれたら、次のコードを使用して配列を設定する必要があります。Next when the View is loaded, we need to populate our array with this 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);

}

ここで、アウトラインビューを作成し、 メインのストーリーボード ファイルをダブルクリックして、Interface Builder で編集するために開きます。Now we need to create our Outline View, double-click the Main.storyboard file to open it for editing in Interface Builder. テーブルを次のようにレイアウトします。Layout the table to look something like the following:

アウトラインビューの作成Creating the outline view

このアウトラインにバインドされたデータを提供するには、 ツリーコントローラー を追加する必要があります。次の手順を実行します。We need to add an Tree Controller to provide bound data to our outline, do the following:

  1. ライブラリインスペクター から インターフェイスエディターツリーコントローラー をドラッグします。Drag an Tree Controller from the Library Inspector onto the Interface Editor:

    ライブラリからツリーコントローラーを選択するSelecting a Tree Controller from the Library

  2. インターフェイス階層 で [ツリーコントローラー ] を選択し、属性インスペクター に切り替えます。Select Tree Controller in the Interface Hierarchy and switch to the Attribute Inspector:

    属性インスペクターの選択Selecting the Attribute Inspector

  3. クラス名として「」と入力し、 PersonModel プラス ボタンをクリックして、3つのキーを追加します。Enter PersonModel for the Class Name, click the Plus button and add three Keys. 名前 Name を、次のように指定 OccupationisManager ます。Name them Name, Occupation and isManager:

    個人モデルに必要なキーパスを追加しています。Adding the required key paths for PersonModel.

  4. これにより、ツリーコントローラーがどのように配列を管理しているか、および (キーを使用して) 公開する必要があるプロパティが示されます。This tells the Tree Controller what it is managing an array of, and which properties it should expose (via Keys).

  5. [ツリーコントローラー ] セクションで、 personModelArray [] に「」と入力し、 NumberOfEmployees Count の下に「」と入力して、リーフの下に「」と入力し isEmployee ますUnder the Tree Controller section, enter personModelArray for Children, enter NumberOfEmployees under the Count and enter isEmployee under Leaf:

    ツリーコントローラーのキーパスの設定Setting the Tree Controller key paths

  6. これにより、子ノードを検索する場所、子ノードの数、現在のノードに子ノードがあるかどうかがツリーコントローラーに示されます。This tells the Tree Controller where to find any child nodes, how many child nodes there are and if the current node has child nodes.

  7. バインドインスペクター に切り替え、[コンテンツ配列] で、[バインド先] と [ファイルの所有者] を選択します。Switch to the Bindings Inspector and under Content Array select Bind to and File's Owner. モデルキーのパス を入力してください self.personModelArray :Enter a Model Key Path of self.personModelArray:

    キーのパスを編集するEditing the key path

  8. これにより、ビューコントローラーで公開したの配列に、ツリーコントローラーが関連付けられ PersonModels ます。This ties the Tree Controller to the array of PersonModels that we exposed on our View Controller.

ここで、アウトラインビューをツリーコントローラーにバインドし、次の手順を実行します。Now we need to bind our Outline View to the Tree Controller, do the following:

  1. [アウトライン] ビューを選択し、 バインドインスペクター で次のように選択します。Select the Outline View and in the Binding Inspector select :

    アウトラインビューとバインドインスペクターを選択します。Selecting the Outline View and Binding Inspector.

  2. アウトラインビュー の [コンテンツ turndown] で、[バインド先] と [ツリーコントローラー] を選択します。Under the Outline View Contents turndown, select Bind to and Tree Controller. arrangedObjects[コントローラーキー ] フィールドに「」と入力します。Enter arrangedObjects for the Controller Key field:

    コントローラーキーの設定Setting the controller key

  3. [ Employee ] 列の下にある テーブルビューセル を選択します。Select the Table View Cell under the Employee column. Turndown の の下にある [バインド] インスペクター で、[テーブルセルビュー****にバインド] を選択します。In the Bindings Inspector under the Value turndown, select Bind to and Table Cell View. objectValue.Nameモデルキーのパス として「」と入力します。Enter objectValue.Name for the Model Key Path:

    モデルキーパスの値 objectValue ドット名を入力します。Entering the model key path value objectValue dot Name.

  4. objectValue は、 PersonModel ツリーコントローラーによって管理されている配列内の現在のです。objectValue is the current PersonModel in the array being managed by the Tree Controller.

  5. [職業] 列の下にある [テーブルビュー] セル を選択します。Select the Table View Cell under the Occupation column. Turndown の の下にある [バインド] インスペクター で、[テーブルセルビュー****にバインド] を選択します。In the Bindings Inspector under the Value turndown, select Bind to and Table Cell View. objectValue.Occupationモデルキーのパス として「」と入力します。Enter objectValue.Occupation for the Model Key Path:

    モデルキーパスの値 objectValue dot を入力します。Entering the model key path value objectValue dot Occupation.

  6. 変更を保存し Visual Studio for Mac に戻り、Xcode と同期します。Save your changes and return to Visual Studio for Mac to sync with Xcode.

アプリケーションを実行すると、の配列がアウトラインに設定され PersonModels ます。If we run the application, the outline will be populated with our array of PersonModels:

アプリケーションを実行します。これにより、個人モデルの配列が作成されます。Running the application, which populates our array of PersonModels.

コレクションビューのデータバインディングCollection view data binding

コレクションビューを使用したデータバインディングは、コレクションにデータを提供するために配列コントローラーが使用されるため、テーブルビューとのバインドとよく似ています。Data binding with a Collection View is very much like binding with a Table View, as an Array Controller is used to provide data for the collection. コレクションビューには事前設定された表示形式がないため、ユーザーの操作に関するフィードバックを提供し、ユーザーの選択を追跡するために、より多くの作業が必要になります。Since the collection view doesn't have a preset display format, more work is required to provide user interaction feedback and to track user selection.

重要

Xcode 7 および macOS 10.11 (以降) の問題により、コレクションビューはストーリーボード (storyboard) ファイルの内部では使用できません。Due to an issue in Xcode 7 and macOS 10.11 (and greater), Collection Views are unable to be used inside of a Storyboard (.storyboard) files. そのため、xib ファイルを引き続き使用して、Xamarin. Mac アプリのコレクションビューを定義する必要があります。As a result, you will need to continue to use .xib files to define your Collection Views for your Xamarin.Mac apps. 詳細については、 コレクションビュー のドキュメントを参照してください。Please see our Collection Views documentation for more information.

ネイティブクラッシュのデバッグDebugging native crashes

データバインディングに誤りを加えると、アンマネージコードで ネイティブクラッシュ が発生し、Xamarin. Mac アプリケーションがエラーで完全に失敗する可能性があります。 SIGABRTMaking a mistake in your data bindings can result in a Native Crash in unmanaged code and cause your Xamarin.Mac application to fail completely with a SIGABRT error:

ネイティブクラッシュダイアログボックスの例Example of a native crash dialog box

通常、データバインディング中のネイティブクラッシュには、主に次の4つの原因があります。There are typically four major causes for native crashes during data binding:

  1. データモデルは、 NSObject またはのサブクラスから継承されません NSObjectYour Data Model does not inherit from NSObject or a subclass of NSObject.
  2. 属性を使用して、プロパティを目的の C に公開していません [Export("key-name")]You did not expose your property to Objective-C using the [Export("key-name")] attribute.
  3. およびメソッドの呼び出しでアクセサーの値の変更をラップしていません WillChangeValue DidChangeValue (属性と同じキーを指定してい Export ます)。You did not wrap changes to the accessor's value in WillChangeValue and DidChangeValue method calls (specifying the same Key as the Export attribute).
  4. Interface Builder の バインドインスペクター に間違ったキーまたは入力ミスのキーがあります。You have a wrong or mistyped Key in the Binding Inspector in Interface Builder.

クラッシュのデコードDecoding a crash

データバインディングでネイティブクラッシュが発生しているので、それを見つけて修正する方法を示すことができます。Let's cause a native crash in our data binding so we can show how to locate and fix it. Interface Builder では、コレクションビューの最初のラベルのバインドをからに変更してみましょう Name TitleIn Interface Builder, let's change our binding of first Label in the Collection View example from Name to Title:

バインドキーの編集Editing the binding key

変更を保存し、Visual Studio for Mac に切り替えて、Xcode と同期し、アプリケーションを実行してみましょう。Let's save the change, switch back to Visual Studio for Mac to sync with Xcode and run our application. コレクションビューが表示されると、がキーを使用して SIGABRT プロパティを公開しないため、アプリケーションは、(Visual Studio for Mac の アプリケーション出力 に示されているように) エラーを一時的にクラッシュし PersonModel Title ます。When the Collection View is displayed, the application will momentarily crash with a SIGABRT error (as shown in the Application Output in Visual Studio for Mac) since the PersonModel does not expose a property with the Key Title:

バインドエラーの例Example of a binding error

アプリケーション出力 のエラーの一番上までスクロールすると、問題を解決するためのキーが表示されます。If we scroll to the very top of the error in the Application Output we can see the key to solving the issue:

エラーログで問題を見つけるFinding the issue in the error log

この行は、バインド先のオブジェクトにキーが存在しないことを示してい Title ます。This line is telling us that the key Title doesn't exist on the object that we are binding to. バインドを Interface Builder に変更し、 Name 保存、同期、リビルド、および実行すると、アプリケーションは問題なく動作するようになります。If we change the binding back to Name in Interface Builder, save, sync, rebuild and run, the application will run as expected without issue.

まとめSummary

この記事では、Xamarin. Mac アプリケーションでのデータバインディングとキー値のコーディングの使用について詳しく説明しました。This article has taken a detailed look at working with data binding and key-value coding in a Xamarin.Mac application. まず、キー値のコード (KVC) とキー値の観測 (KVC) を使用して、C# クラスを目的の C に公開する方法を見てきました。First, it looked at exposing a C# class to Objective-C by using key-value coding (KVC) and key-value observing (KVO). 次に、KVO に準拠したクラスを使用し、データを Xcode の Interface Builder の UI 要素にバインドする方法について説明しました。Next, it showed how to use a KVO compliant class and Data Bind it to UI elements in Xcode's Interface Builder. 最後に、 配列コントローラーツリーコントローラー を使用した複雑なデータバインディングについて説明しました。Finally, it showed complex data binding using Array Controllers and Tree Controllers.