Observer pattern on class properties?

Hi all,

I’m just getting started with Xojo, but I love it so far! Please forgive me if this is a basic question. I’m trying to implement the Observer pattern described here: Design Patterns in Xojo: Observer, Part II – Xojo Programming Blog. I understand it, and have implemented the classes mentioned on the article in my project, and it works when I bind controls to text labels. However, I am trying to modify the code to work on a custom class and UI controls. I have a custom class called “Device” with various computed properties of different types: BacklightSetting (String), BatteryLevel (Integer), ProgrammingEnabled (Boolean), etc. I have a bunch of labels in a window that I would like to update if code updates any of the properties in a Device object.

My plan was to call sendNotification from all the Setters, like so:

dim myNotificationCenter as NotificationCenter = NotificationCenter.sharedInstance
mynotificationcenter.sendNotification(me,"valueChanged",me.BacklightSetting)

and then the BacklightSettingLabel’s newValueReceived event would have:

me.Text = Device(value).BacklightSetting

and so on. I modified the example on the article so that the register and sendNotification methods of the NotificationCenter class has objects being passed as objects, rather than RectControls. This works if my properties are any class types, but since some of them are normal datatypes, I get errors like so when registering the properties with the NoticiationCenter object:

dim miNotificationCenter as NotificationCenter = NotificationCenter.sharedInstance
//sourceControl(NotificationReceiver, observedObject as RectControl, message as text)
miNotificationCenter.register(BacklightLabel,app.CurrentDevice.BacklightSetting, "valueChanged"

Error: Type mismatch error.  Expected Object, but got String

I tried to cast the BacklightSetting property as an object when calling sendNotification, but I get the same error. I realize this is probably because Strings in Xojo are not objects like in some other languages. And since my properties are various data types, i can’t just change the arguments to expect a string.

Any suggestions on how to tackle this? Thank you!

1 Like

But you can have two (or more) methods under the same name with different-typed parameters (AKA “overloading” the method).

For example:

register(sourceControl as NotificationReceiver, observedObject as RectControl, message as text)

register(sourceControl as NotificationReceiver, observedObject as String, message as text)

register(sourceControl as NotificationReceiver, observedObject as Boolean, message as text)

register(sourceControl as NotificationReceiver, observedObject as Integer, message as text)

As long as the ordering and datatypes of the parameters make it unambiguous which version should be used, the compiler will figure it out.

miNotificationCenter.register(BacklightLabel, "My String", "valueChanged")
miNotificationCenter.register(BacklightLabel, MyRectControl, "valueChanged")
miNotificationCenter.register(BacklightLabel, True, "valueChanged")
' etc.

You will of course have to write code for each method that knows what to do with the datatype you gave it.

3 Likes

Andrew, thank you so much, you’ve really helped me out! Once you say it, it seems so obvious! :smile:

1 Like

Keep in mind that NotificationCenter is an iOS framework class. If you ever try to use your code in an iOS project, you’ll have problems.

1 Like

Greg, thanks, but I was using the custom NotificationCenter class implemented in the blog entry I mentioned. But, good to know! I didn’t know iOS has that framework.