No
The CLASS that implements it would have this code in IT to return the correct reference to the control
Notice in the example Car has code for MakeNoise and Dog has code for MakeNoise
NOT the interface itself
Why ? an Interface is literally a list of methods that are GUARANTEED to exist on anything that implements the interface
But the interface does not say HOW to implement it - hence it has no code
Thanks, Norman. I thought that was probably the case and tried putting it in the Open event of the WebPage that will have the container embedded in it. Obviously I’m not doing it right. I put something like this in that event and was told End Interface was a syntax error:
Interface MyInterface
Function TextField1() As WebTextField
Function Slider1() As WebSlider
End Interface
You should read or re-read Norman’s long post above. Best would be to open a new project and add the elements and the code he describes. You’ll probably grasp the concept of interfaces easier that way. Just reading the code has obviously not enlightened you.
You should read or re-read Norman’s long post above. Best would be to open a new project and add the elements and the code he describes. You’ll probably grasp the concept of interfaces easier that way. Just reading the code has obviously not enlightened you.[/quote]
After spending a lot of time re-reading Will’s code, I think I finally get what’s needed here. It creates Functions in the Interface that, in virtue of their names, mirror Controls in the WebContainers (before they are renamed), while Controls in the WebContainers are renamed and Functions in the WebContainers mirror its Controls, in virtue of having names that match the Controls’ original names, with each such Function returning the “inner” renamed field.
If thinking of it this way fails me, creating a new project implementing Norman’s steps is my next step here. I feel like I’ve wasted so much of users’ time here. Thanks for your patience.
whats important is that it is an interface and so you can treat ANYTHING that implements that interface interchangeably
I would suggest NOT relying on Will’s “undocumented” mechanism as that is very fragile (and could easily be broken by changes)
Interface MyInterface
Function GetTextField() As WebTextField
Function GetSlider() As WebSlider
End Interface
Class DesktopContainer Inherits WebContainer Implements MyInterface
Private Control TextField1 As WebTextField
Private Control Slider1 As WebSlider
Function GetTextField() As WebTextField
return TextField1
End Function
Function GetSliderSlider() As WebSlider
return slider1
End Function
End Class
Thanks, Norman. The reason I thought the Interface Functions needed to match the currently existing Control Names (before being renamed) is because my Methods/Handlers use those names right now and I didn’t want to rewrite them.
But it sounds like this method, which was designed to help me use existing Control Names, is what you say is fragile, and what Will admits is not documented and might break.
Just to make sure we’re on the same page here, I’m working off Will’s original post re Interface:
Class DesktopWebContainer inherits WebContainer
Control TextField1 As TextField
End Class
Interface MyInterface
Function TextField1() As TextField
End Interface
Class DesktopWebContainer inherits WebContainer implements MyInterface
Private Control innerTextField1 As TextField
Function TextField1() As TextField
return innerTextField1
End Function
End Class
I think the stuff he posted later, which he called undocumented, was a little different.
So, Norman. It looks like the part that’s missing in the undocumented code is stuff like this, where I create a Function for each Control and have it return the originally-named Control:
Class DesktopWebContainer inherits WebContainer implements MyInterface
Private Control innerTextField1 As TextField
Function TextField1() As TextField
return innerTextField1
End Function
End Class
That sort of Function is missing in the later code posted as undocumented, but is included in his earlier code and what you just posted.
Yep. That’s exactly what you suggested in your last post, very succinctly and clearly. But it wasn’t until I re-read that sort of code in Will’s post over lunch, very slowly, about 10 times, that I finally got the idea behind it … that the Interface will end up using a method that will stand for a Control so that I could use that instead of a direct reference to an actual Control, so existing Methods/Handlers won’t need to be rewritten. I kept thinking that that code was somehow creating a Control in the Interface, while I kept reading elsewhere that Interfaces don’t have Controls.
FWIW, the code snippet that I kept stumbling on was this:
Interface MyInterface
Function TextField1() As TextField
End Interface
That looked to me like it was creating a TextField1 in the Interface. I know that’s obviously not what it’s doing, but this relatively new Xojo coder thought that until today at lunch. Once I got what it was doing, it started to fall in place for me.
Yeah that little snippet takes advantage of an undocumented thing that exists when you create a window.
There is an undocumented method that returns an instance of a control that is named whatever you named the control.
Suppose you dropp a text field on a layout and call it “MyCoolControl”
When that window is compiled there is a method called “MyCoolControl” that returns THAT control
BUT like I said this is undocumented and relying on it is NOT a good idea as we could make changes that would break this
Thats what Will’s code was relying on - that there WILL be a method with the right name when the app is compiled
I’d rather be VERY explicit about this & not rely on undocumented behaviour
Uh, Norman, he’s renaming the controls and then creating methods with the original names, for the sake of not having to change a bunch of code. There’s nothing undocumented about that. He’s not going down the route of overloading the control name.
Ok, here is what I’ve been doing as far as refactoring this stuff, based on what I have learned in this thread …
[Pre-existing stuff]
WebPage1 is to have one of two WebContainer embedded in it:
DesktopWebContainer
MobileWebContainer
WebContainer1 is a Property of WebPage1
[New stuff]
I created MyInterface with no pre-existing Methods.
WebPage1 implements MyInterface.
DesktopWebContainer implements MyInterface.
MobileWebContainer implements MyInterface.
WebContainer1 (Property of WebPage1) now has its super as MyWebInterface.
Each Control in each WebContainer is now Private and is renamed as follows:
TextField1 becomes innerTextField1
ProgressBar1 becomes innerProgressBar1
etc.
For each Control in each WebContainer, there is a new Method with the original name of the Control:
Method TextField1 returns innerTextField1 As WebTextField
Method ProgressBar1 returns innerProgressBar1 As WebProgressBar
etc.
For each Control in the two WebContainers, a Method in MyInterface is created with the original name of the Control:
Method TextField1 returns As WebTextField
Method ProgressBar1 returns As WebProgressBar
etc.
In WebPage1.Shown, whatever WebContainer instance is selected (DesktopWebContainer or MobileWebContainer), Property WebContainer1 is assigned that WebContainer instance.
All my pre-existing methods referenced Controls via WebContainer1 (e.g., WebContainer1.TextField1). Now they still do, in virtue of the above setup.
Can I safely assume none of the above relies an any undocumented features?
Ok. I finally finished doing all the above work for every Control in the two WebContainers. After doing that, compilation stopped out at a series of errors about WebPage1.Name, each referencing a different Control in the two WebContainers. If the Control referenced in each error is c, then each error looks like this:
[WebPage1.Name]
This class is missing the c method from the interface MyInterface.
WebPage1
Then there are two more similar errors, one for each of the two WebContainers:
[DesktopWebContainer.Name]
This class is missing the WebPage1 method from the interface MyInterface.
DesktopWebContainer
[MobileWebContainer.Name]
This class is missing the WebPage1 method from the interface MyInterface.
MobileWebContainer
If I copy all the Methods found in MyInterface to WebPage1, it no longer complains and works fine when run. But I have a feeling someone here is going to tell me I don’t have to clutter WebPage1 with copies of all those MyInterface Methods. Is there some simple hook I can put there to cover this?
I just figured it out. I had WebPage1 implementing MyInterface. When I unchecked that, it works fine. Now I only have the two WebContainers implementing that interface.
Though this is all working beautifully, today I experimented and replaced all “new names” for controls with original names, and it still works. That is, for a control that was rename to innerTextField1, I changed it back to TextField1, so I now have a method named TextField1 that returns TextField1 instead of innerTextField1. And the interface still has a method named TextField1. It works without having to rename the original control something like innerTextField1 and having the method TextField1 return innerTextField1.
I assume it’s still best to use the renaming method, just in case some future version of Xojo stumbles on the control and method having the same name, and not knowing with is intended when the interface method of the same name is triggered.