Quantcast
Channel: Xamarin.Mac — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 1429

Xamarin Mac KVO model bindings - change fires twice

$
0
0

I am trying to implement KVO bindings in a Xamarin Mac desktop app.
I have followed the docs, and it is working, but the bindings appear to trigger 2 change events each time!

If I create a KVO model with a binding like this...

    private int _MyVal;
    [Export("MyVal")]
    public int MyVal
    {
        get { return _MyVal; }
        set
        {
            WillChangeValue("MyVal");
            this._MyVal = value;
            DidChangeValue("MyVal");
        }
    }

And bind a control to it in Xcode under the bindings section with the path self.SettingsModel.MyValue

It all appears to work fine, the control shows the model value, changing the model value programmatically updates the control and changing the control updates the model value.

However, it runs the change event twice.

I am listening to the change so I can then hit an API with the value.

SettingsModel.AddObserver(this, (NSString)key, NSKeyValueObservingOptions.New, this.Handle);

Then later...

 public override void ObserveValue(NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context)
    {
        switch (keyPath)
        {
            case "MyValue":

            // CODE HERE THAT UPDATES AN API WITH THE VALUE
            // But this handler fires twice.


            break;
        }
    }

Im not sure if its Xamarin or XCode that is causing the double trigger.

Interestingly, if you don't specify the Xcode WillChangeValue and DidChangeValue methods, then it doesn't trigger twice - as though Xamarin has automatically triggered the change once. However, it no longer triggers a change when programmatically updating the model value...

[Export("MyVal")]
public int MyVal { get; set }

The above will work for the Xcode controls, they will update the model and trigger a change event.

But programmatically updating it

this.SettingsModel.MyVal = 1;

Does not trigger the change event.

It's very confusing, any idea on how to stop 2 change events firing, as I don't want to hit the API twice every time!

When it fires twice, the stack trace (abridged) for the first has...

MainViewController.ObserveValue
ObjCRuntime.Messaging.void_objc_msgSendSuper_IntPtr()
Foundation.NSObject.DidChangeValue(string forKey)
CameraSettingsModel.set_MyValue(int value)
AppKit.NSApplication.NSApplicationMain()
AppKit.NSApplication.Main(string[] args)
MainClass.Main(string[] args)

Which looks fine, but the second...

MainViewController.ObserveValue
AppKit.NSApplication.NSApplicationMain()
AppKit.NSApplication.Main(string[] args)
MainClass.Main(string[] args)

Has no mention of the Setting Model triggering the event


Viewing all articles
Browse latest Browse all 1429

Trending Articles