我正在尝试在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。
有趣的是,如果您未指定XcodeWillChangeValue
和DidChangeValue
方法,那么它不会触发两次-好像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] 删除。
我来说两句