Xamarin Mac KVO模型绑定-两次转换

马特·布赖森

我正在尝试在Xamarin Mac桌面应用程序中实现KVO绑定。我已经关注了文档,并且该文档正在运行,但是每次绑定似乎都会触发2个change事件!

如果我用这样的绑定创建KVO模型...

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

并在bindings具有路径部分下的Xcode中将控件绑定到它self.SettingsModel.MyValue

看起来一切正常,控件显示模型值,以编程方式更改模型值会更新控件,而更改控件会更新模型值。

但是,它将两次运行change事件。

我正在听更改,因此可以使用该值访问API。

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

后来...

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

我不确定是否是导致双重触发的Xamarin或XCode。

有趣的是,如果您未指定XcodeWillChangeValueDidChangeValue方法,那么它不会触发两次-好像Xamarin已自动触发一次更改。但是,以编程方式更新模型值时,它不再触发更改。

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

上面的代码适用于Xcode控件,它们将更新模型并触发更改事件。

但是以编程方式对其进行更新

this.SettingsModel.MyVal = 1;

不触发更改事件。

关于如何停止触发2个更改事件的想法非常令人困惑,因为我不想每次都两次点击API!

当它触发两次时,第一个的堆栈跟踪(删节)具有...

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) 

看起来不错,但是第二个...

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

没有提及触发事件的设置模型

克里斯·哈蒙斯

您正在达到目标-收到一次KVC更改的2条KVO通知

并需要覆盖显示的AutomaticallyNotifyObserversForKey。

可可通过为您发送通知来“帮您一个忙”,这很棒,除了您的托管版本也发送通知。

看起来像这样:

    [Export ("automaticallyNotifiesObserversForKey:")]
    public static new bool AutomaticallyNotifiesObserversForKey (string key) => false;

    bool _checkValue;

    [Export("CheckValue")]
    public bool CheckValue
    {
        get { return _checkValue; }
        set
        {
            WillChangeValue("CheckValue");
            _checkValue = value;
            DidChangeValue("CheckValue");
        }
    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad();

        this.AddObserver("CheckValue", NSKeyValueObservingOptions.New, o =>
        {
            Console.WriteLine($"Observer triggered for {o}");
        });

        CheckValue = false;

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章