Somehow I’ve never used delegates in RS/Xojo, and now that I want to use them, the documentation gives me almost nothing, and what’s there is opaque.
I suppose there must be some examples, but I can’t seem to find them.
It would really be nice to have some documentation.
I’ve Googled this, read many pages about Xojo delegates, and attempted to implement a delegate, but it doesn’t work. Apparently I can’t add a delegate as a property to a window, and assign its value in the Open event handler? The documentation says nothing about this.
What I want to do here is route events coming from a callback dynamically without using conditionals in the receiving method. (A conditional check every time an event occurs would slow everything down unnecessarily, and change of routing only needs to take place rarely - during a modal sheet window for example). So, I want to delegate the incoming events to one receiving method or another. Maybe I misunderstand how delegates work in Xojo? I’ve searched the forums and found nothing very useful. Any help is appreciated.
… well, it looks like I can add events to the window, and assign the receiving methods using AddHandler (and RemoveHandler).
But I’d still like to know how to use delegates in Xojo. The Delegate object and the things it needs: AddressOf and WeakAddressOf have almost no documentation or examples.
Delegates are a TYPE - think of them like a new Class
So yes you can define a property that is a delegate type
But what you assign to the delegate would be the ADDRESS OF the method that IS the delegate method
If you have an older install of Xojo / RB then in the 2013r2.1 Examples there is one inside Examples > Advanced > Delegates
This is one of those things where you’ll have a “OHHHH” kind of moment where it all becomes clear. At least, that’s how it was for me.
Start by inserting the Delegate into the class, module, or window that needs to call it. The delegate is just a framework for a method: What its parameters will be and what its return type will be, if any. (Suggestion: Make the first parameter “sender” as whatever class is making the call.
When you create a method elsewhere that will be called as a delegate, it simply has to match the parameters and the return type. Then you can create some mechanism by which to register that method with the caller, usually some sort of Register method and a property that holds the delegate. (That property can be an array if you need to call more than one delegate.)
You record the method that will act as a delegate with AddressOf, so if the method is called “WriteSomething”, and your caller has a Register method, you would use
Register( AddressOf WriteSomething ). The Register method’s declaration would be something like
Sub Register (m As MyDelegate)
myDelegateProp = m
When it comes time to use the delegate, you’d do something like:
if myDelegateProp <> nil then
myDeletegatePro.Invoke( self, param1, param2,
Okay, thanks Norman and Kem.
I can add a property of type Delegate to a window. But I can’t assign its value.
self.myDelegate = WeakAddressOf( self.myObject.myMethod )
I get a Syntax Error.
Norman, I have 2013 releases 1, 2, 3, 3.1, 3.3, and 4.1 … not 2.1 unfortunately and I can’t find the example project anywhere.
Typo on my part
It seems to have gone away in 2013
Did you declare the property like
myDelegate As Delegate? If so, that’s wrong. Before you create the property, you have to create the delegate. Look under the Insert menu and you’ll see that’s one of the choices. Once it’s inserted, you set it up as you would a method in terms of parameters and return type, if any.
So let’s say you insert the Delegate and call it “MyMethodDelegate”. You then declare your property as
myDelegate As MyMethodDelegate, and finally use
myDelegate = WeakAddressOf( self.myObject.myMethod ). As long as the parameters and return type of myMethod match what you’ve set up in MyMethodDelegate, it will work.
Yup, that’s what I did. Okay, let me follow your directions here …
Norman, I’ve got RS going back to version 2005 I think … somewhere! (not on this machine).
… It appears that this first step is all I was missing; I think I understand how they are supposed to work. Maybe I’m a little dense, but shouldn’t this be in the documentation?
To create a Delegate
- Insert > Delegate
- name the delegate and give it the params you need
Then what’s in the LR starts to make a little sense, although it’s still obtuse.
I’ll take a look at the LR tomorrow and discuss with Paul if/where it needs clarification. I think the User Guide might be helpful here, if you haven’t looked.
Thank you, Kem. And my apologies, I don’t know why I forgot all about the User Guide; will check it as well.
It makes perfect sense that the delegate can’t be added directly as a property without defining what its parameters will be. This aspect of creating them is just absent from the LR, so I think it would be a good idea to add that important info.
OK, I think it’s:
- Insert > Delegate
- name the delegate and give it the params you need: ex/ myDelegate( param1 as integer )
- add a property cast as type the name you gave the delegate in step 2
- assign the method to the property in step 3 using AddressOf or WeakAddressOf
Getting closer. It’s very flexible! … but not intuitive.
Remember the LR is a “language reference” not a “how to guide” like the User Guide is
You’ve got it. As I mentioned earlier, I suggest that the first parameter of your delegate be sender As SendingClass so that the method acting as delegate knows where it was called from. If you don’t need it, no harm done, but it’s less work to do this up front than to go back and rework it later.
Point taken. The product is so easy to use, that I haven’t needed to consult the User Guide since I first learned RB way back when, so it didn’t even occur to me
Still, I’d point out that the LR usually has at least a brief explanation and example code, and in the case of Delegates, AddressOf, and WeakAfddressOf, the LR content for these items seems almost useless to me. I know they are more advanced, but what I wasn’t getting straight wasn’t anything advanced, it was just a simple how-to.
Yes, your suggestion, even if it’s not always necessary, makes a lot of sense as good transportable OOP.
Thank you both very much for the help!