Dynamically change Property Type?

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

That’s obvious.

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=254562:@Eli Ott]That’s obvious.

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.

the names of the functions is immaterial

you could name them Foo, Bar, Baz etc

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.

Not Documented = this may come back to bite you in the butt later on :slight_smile:

Norman,

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.

Yeah basically the same as what I was suggesting

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.

Which is what I suggested you do in my last post. :wink:

Tim,

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?

I believe so.

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’d really need to see a copy of the project to make further recommendations

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.