Xamarin.ios의 데이터 바인딩 및 키-값 코딩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.ios 응용 프로그램에서 c # 및 .NET으로 작업 하는 경우 목표-CXcode 에서 작업 하는 개발자가 동일한 키-값 코딩 및 데이터 바인딩 기술에 액세스할 수 있습니다.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. Xamarin.ios는 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.

Xamarin.ios 응용 프로그램에서 키-값 코딩 및 데이터 바인딩 기술을 사용 하 여 UI 요소를 채우고 사용 하기 위해 작성 하 고 유지 관리 해야 하는 코드의 양을 크게 줄일 수 있습니다.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.ios 응용 프로그램에서 키-값 코딩 및 데이터 바인딩 작업의 기본 사항을 다룹니다.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.ios 내부 문서에서 c # 클래스/메서드를 목표로 표시 하는 방법에 대해 살펴볼 수 있습니다 Register . c Export # 클래스를 목표-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.ios 응용 프로그램에서 키-값 코딩 규격 접근자를 구현 하 여 키-값 관찰 (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.

Xamarin.ios 응용 프로그램에서 키-값 코딩 및 데이터 바인딩 기술을 사용 하 여 UI 요소를 채우고 사용 하기 위해 작성 하 고 유지 관리 해야 하는 코드의 양을 크게 줄일 수 있습니다.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 및 KVO 기술을 통해 속성에 액세스 하는 데 사용 되는 키 값을 정의 합니다.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.

마지막으로 속성의 값에 대 한 키 값이 변경 될 수 있도록 접근자는 WillChangeValue 특성과 동일한 키를 지정 하 여 및 메서드 호출에서 해당 값에 대 한 변경 내용을 래핑해야 합니다 DidChangeValue 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)을 사용 하 여, 관찰자를 KVC 규격 클래스의 특정 키에 연결 하 고, 해당 키에 대 한 값이 수정 될 때마다 (KVC 기술을 사용 하거나 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의 키-값 관찰 프로그래밍 가이드를참조 하세요.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.ios 응용 프로그램을 보다 유연 하 고 쉽게 유지 관리할 수 있도록 합니다.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.ios 응용 프로그램에 정의 된 KVC/KVO 규격 클래스가 있어야 바인딩에 대 한 데이터 모델 역할을 할 수 있습니다.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).

첫째, 직원은 관리자가 될 수 있으므로를 사용 하 여 NSArray 관리 되는 직원 들이 연결 될 수 있도록 (특히, 값을 수정할 수 있음)을 사용 했습니다 NSMutableArray .First, 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; }
}

다음 두 가지 사항을 참고 하세요.Two things to note here:

  1. NSMutableArray이는 테이블 뷰, 개요 뷰컬렉션과같은 appkit 컨트롤에 데이터를 바인딩하기 위한 요구 사항 이므로 표준 c # 배열 또는 컬렉션 대신를 사용 했습니다.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).

다음으로 일부 특수 이름 public 메서드를 추가 하 여 배열 컨트롤러트리 컨트롤러를 지원 해야 합니다.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.

이러한 메서드 내에서 WillChangeValue DidChangeValue 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.ios 응용 프로그램에 추가 하겠습니다 PersonModel .For 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의 기본 storyboard 파일에 새 뷰 컨트롤러 를 추가 하 고 해당 클래스의 이름을로 지정 합니다 SimpleViewController .First, let's add a new View Controller to our Main.storyboard file in Interface Builder and name its class SimpleViewController:

새 뷰 컨트롤러 추가Adding a new view controller

그런 다음 Mac용 Visual Studio로 돌아가서 프로젝트에 자동으로 추가 된 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에서 storyboard 편집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. 직원 이름 텍스트 필드를 선택 하 고 바인딩 검사자로 전환 합니다.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 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 the key path

  4. Employee is a Manager 확인란을 선택 하 고 바인딩 대상 상자를 선택 하 고 드롭다운에서 단순 보기 컨트롤러 를 선택 합니다.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:

    키 경로 입력Entering the key path

  5. 직원의 관리 되 는 텍스트 필드를 선택 하 고 바인딩 대상 상자를 선택 하 고 드롭다운에서 단순 보기 컨트롤러 를 선택 합니다.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 the key path

  6. 직원이 관리자가 아니면 직원의 관리 되는 레이블과 텍스트 필드의 수를 숨기려는 것입니다.If the employee is not a manager, we want to hide the Number of Employees Managed Label and Text Field.

  7. 직원의 관리 되 는 레이블 수를 선택 하 고 Hidden 접혀를 확장 한 다음 바인딩 대상 상자를 선택 하 고 드롭다운에서 단순 보기 컨트롤러 를 선택 합니다.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:

    키 경로 입력Entering the key path

  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. 변경 내용을 저장 하 고 Xcode와 동기화 할 Mac용 Visual Studio로 돌아갑니다.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. 예를 들어 직원의 선택을 취소 하면 관리자가 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의 기본 storyboard 파일에 새 뷰 컨트롤러 를 추가 하 고 해당 클래스의 이름을로 지정 합니다 TableViewController .First, let's add a new View Controller to our Main.storyboard file in Interface Builder and name its class TableViewController:

새 뷰 컨트롤러 추가Adding a new view controller

다음으로 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 데이터 모델 정의 섹션에서 위의 클래스에서와 같이 배열 컨트롤러에서 컬렉션의 데이터를 읽고 쓰기 위해 특별히 명명 된 네 public 메서드를 노출 했습니다 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 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 클래스 이름으로를 입력 하 고 더하기 단추를 클릭 한 다음 세 개의 키를 추가 합니다.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

  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 Binding Inspector

  2. 표 내용 접혀에서 바인딩 및 배열 컨트롤러 선택 합니다.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. 바인딩 검사자 접혀에서 바인딩 및 테이블 셀 뷰를 선택 합니다.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:

    모델 키 경로 설정Setting the model key path

  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. 바인딩 검사자 접혀에서 바인딩 및 테이블 셀 뷰를 선택 합니다.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

  6. 변경 내용을 저장 하 고 Xcode와 동기화 할 Mac용 Visual Studio로 돌아갑니다.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

개요 보기 데이터 바인딩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의 기본 storyboard 파일에 새 뷰 컨트롤러 를 추가 하 고 해당 클래스의 이름을로 지정 합니다 OutlineViewController .First, let's add a new View Controller to our Main.storyboard file in Interface Builder and name its class OutlineViewController:

새 뷰 컨트롤러 추가Adding a new view controller

다음으로 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 데이터 모델 정의 섹션에서 위의 클래스에서와 마찬가지로, 트리 컨트롤러에서 컬렉션의 데이터를 읽고 쓰기 위해 특별히 명명 된 네 public 메서드를 노출 했습니다 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 클래스 이름으로를 입력 하 고 더하기 단추를 클릭 한 다음 세 개의 키를 추가 합니다.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

  4. 이를 통해 트리 컨트롤러에서 배열을 관리 하는 대상 및 키를 통해 노출 해야 하는 속성을 알 수 있습니다.This tells the Tree Controller what it is managing an array of, and which properties it should expose (via Keys).

  5. 트리 컨트롤러 섹션에서 personModelArray 자식에 대해를 입력 하 NumberOfEmployees개수 아래에을 입력 한 다음 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 Binding Inspector

  2. 개요 보기 내용 접혀에서 바인딩 및 트리 컨트롤러 선택 합니다.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. 바인딩 검사자 접혀에서 바인딩 및 테이블 셀 뷰를 선택 합니다.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:

    모델 키 경로 입력Entering the model key path

  4. objectValuePersonModel 트리 컨트롤러에서 관리 중인 배열의 현재입니다.objectValue is the current PersonModel in the array being managed by the Tree Controller.

  5. 직업 열 아래에서 테이블 뷰 셀 을 선택 합니다.Select the Table View Cell under the Occupation column. 바인딩 검사자 접혀에서 바인딩 및 테이블 셀 뷰를 선택 합니다.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:

    모델 키 경로 입력Entering the model key path

  6. 변경 내용을 저장 하 고 Xcode와 동기화 할 Mac용 Visual Studio로 돌아갑니다.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

컬렉션 뷰 데이터 바인딩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 파일 (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.ios 앱에 대 한 컬렉션 뷰를 정의 해야 합니다.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.ios 응용 프로그램이 오류가 발생 하 여 완전히 실패 합니다 SIGABRT .Making 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

일반적으로 데이터 바인딩 중에 기본 충돌의 네 가지 주요 원인은 다음과 같습니다.There are typically four major causes for native crashes during data binding:

  1. 데이터 모델이 NSObject 또는의 서브 클래스에서 상속 되지 않습니다 NSObject .Your 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 Title .In Interface Builder, let's change our binding of first Label in the Collection View example from Name to Title:

바인딩 키 편집Editing the binding key

변경 내용을 저장 하 고, Mac용 Visual Studio으로 다시 전환 하 여 Xcode와 동기화 하 고, 응용 프로그램을 실행 해 보겠습니다.Let's save the change, switch back to Visual Studio for Mac to sync with Xcode and run our application. 컬렉션 뷰가 표시 되 면이 키가 포함 된 속성을 노출 하지 않기 때문에 응용 프로그램은 오류와 함께 일시적으로 중단 됩니다 SIGABRT (Mac용 Visual Studio의 응용 프로그램 출력 에 표시 됨) 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.ios 응용 프로그램에서 데이터 바인딩 및 키-값 코딩을 사용 하는 방법에 대해 자세히 살펴봅니다.This article has taken a detailed look at working with data binding and key-value coding in a Xamarin.Mac application. 먼저 KVC (키-값 코딩) 및 키-값 관찰 (KVO)을 사용 하 여 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.