The Monobjc bridge provides support for Cocoa Bindings. For more informations on bindings, take a look at [Cocoa Bindings Programming Guide][].

Writing a Key-Value compliant classes

Writing a compliant class is no more different than in Objective-C. The formalism of the KVC is easily reproduced, even with .NET properties. Do not forget to expose the field or the getter and the setter to the Objective-C runtime with attributes.

When working with Cocoa Bindings, you have to notify the listeners that the value for a key has changed. This can be done with the 'willChangeValueForKey' and 'didChangeValueForKey' methods around the code block that set the new value.

The listing below shows an example of a KVO compliant class:

using System;
using Monobjc.AppKit;
using Monobjc.Foundation;

namespace Monobjc.Samples.CGRotation
{
    [ObjectiveCClass]
    public class Controller : NSObject
    {
        // ...

        public float Rotation
        {
            [ObjectiveCMessage("rotation")] // <-- Exposed method for getter
            get
            {
                return this.rotation;
            }
            [ObjectiveCMessage("setRotation:")] // <-- Exposed method for setter
            set
            {
                this.WillChangeValueForKey("rotation"); // <-- Prepare for value change

                if (value >= 360.0f)
                {
                    while (value >= 360.0f)
                    {
                        value -= 360.0f;
                    }
                }
                else if (value < 0.0f)
                {
                    while (value < 0.0f)
                    {
                        value += 360.0f;
                    }
                }
                this.rotation = value;
                this.imageView.SetRotation(360.0f - value);
                this.imageView.NeedsDisplay = true;

                this.DidChangeValueForKey("rotation"); // <-- Value change has occured
            }
        }

        // ...

        public float ScaleX
        {
            [ObjectiveCMessage("scaleX")] // <-- Exposed method for getter
            get
            {
                return this.scaleX;
            }
            [ObjectiveCMessage("setScaleX:")] // <-- Exposed method for setter
            set
            {
                this.WillChangeValueForKey("scaleX"); // <-- Prepare for value change

                this.imageView.SetScaleX(this.scaleX = value);
                if (this.preserveAspectRatio)
                {
                    this.imageView.SetScaleY(this.ScaleX);
                }
                this.imageView.NeedsDisplay = true;

                this.DidChangeValueForKey("scaleX"); // <-- Value change has occured
            }
        }


        // ...
    }
}