WebContainer Control Issues

  1. 4 months ago

    Stephen P

    Apr 20 Pre-Release Testers, Xojo Pro

    Hi,

    This is a follow-on from my post yesterday:

    https://forum.xojo.com/53493-enumerating-web-controls/p1#p433217

    The issue is that although I am able to enumerate through the controls on a web page and find the containers with my special property (as in the above link), I (also in same link) need to cast the control to the type of class in order to get at some properties:

    tn = ContactForm6(cont).tablename

    But when I try to duplicate the control, the SuperClass is ContactForm61 and so the cast fails. Any ideas ? Is there a different approach maybe ? All I'm trying to do is locate CC's on a page with my custom property then read some other properties from it.

    Shouldn't be that hard right ?

    Thanks,
    Steve

    If I understand your problem correctly, then you need to:

    • Subclass WebContainer by creating a new Class and setting its Super to WebContainer. Let's call it: MyBaseContainer
    • Add your property to MyBaseContainer.
    • Make all existing WebContainers that need this property children of MyBaseContainer (i.e. set their Super to MyBaseContainer).
    • Delete the property from the child containers. They now inherit it from MyBaseContainer.
    • Now define Foo() in MyBaseContainer. If there is only one variation of Foo() then the code goes in MyBaseContainer.Foo(). If each child of MyBaseContainer needs to implement its own Foo() then define Foo() in MyBaseContainer as an empty method with the parameters/return expected, and code Foo() in each subclass. You can mix and match. A default Foo() can exist in MyBaseContainer and a few subclasses can override MyBaseContainer.Foo() (replace behavior) and even call it themselves using Super.Foo() thereby adding behavior.

    Now forget Introspection. Loop through your page controls and test (IsA) for MyBaseContainer. Children of MyBaseContainer will test TRUE. If you have a MyBaseContainer, cast the type, check the property directly, and call Foo() directly as needed. This will be faster than Introspection.

    Side note: another solution would be to define an interface that any class can implement. You can IsA for an interface, cast to an interface, and call methods defined in the interface. But you would also have to define accessor methods for your property in this case since a Class Interface cannot define properties, only methods.

  2. Stephen P

    Apr 20 Pre-Release Testers, Xojo Pro

    PS Reason for duplication is because I want to change the members of the control.

  3. James S

    Apr 20 Pre-Release Testers, Xojo Pro

    use the “isa” command to see if the container is an instance of your specific container before you cast to it something like:

    if cont isa ContactForm6 then
    tn = ContactForm6( cont).tablename
    end if

  4. Stephen P

    Apr 20 Pre-Release Testers, Xojo Pro

    Ahh ok James thanks. The only problem is that if I create say 6 duplicates, then I'll have to code for the 6 variants. The idea is that it is determined at runtime.

    There must be a way to loop through all controls and determine type of container control with my custom property ? AND get the value of a couple of properties from the control ??

    Thanks,
    Steve

  5. Daniel T

    Apr 22 Pre-Release Testers, Xojo Pro Answer

    If I understand your problem correctly, then you need to:

    • Subclass WebContainer by creating a new Class and setting its Super to WebContainer. Let's call it: MyBaseContainer
    • Add your property to MyBaseContainer.
    • Make all existing WebContainers that need this property children of MyBaseContainer (i.e. set their Super to MyBaseContainer).
    • Delete the property from the child containers. They now inherit it from MyBaseContainer.
    • Now define Foo() in MyBaseContainer. If there is only one variation of Foo() then the code goes in MyBaseContainer.Foo(). If each child of MyBaseContainer needs to implement its own Foo() then define Foo() in MyBaseContainer as an empty method with the parameters/return expected, and code Foo() in each subclass. You can mix and match. A default Foo() can exist in MyBaseContainer and a few subclasses can override MyBaseContainer.Foo() (replace behavior) and even call it themselves using Super.Foo() thereby adding behavior.

    Now forget Introspection. Loop through your page controls and test (IsA) for MyBaseContainer. Children of MyBaseContainer will test TRUE. If you have a MyBaseContainer, cast the type, check the property directly, and call Foo() directly as needed. This will be faster than Introspection.

    Side note: another solution would be to define an interface that any class can implement. You can IsA for an interface, cast to an interface, and call methods defined in the interface. But you would also have to define accessor methods for your property in this case since a Class Interface cannot define properties, only methods.

  6. Stephen P

    Apr 23 Pre-Release Testers, Xojo Pro

    Thanks vm for the detailed reply Daniel. I did, after a lot of reading, come to the realisation of how to achieve this without introspection but your reply put the pieces together for me really well :-)

  7. Daniel T

    Apr 23 Pre-Release Testers, Xojo Pro

    No problem Stephen. I only wish I had posted it sooner!

  8. James S

    Apr 24 Pre-Release Testers, Xojo Pro

    another technique you can use is the class Interface. You can define a class interface that has those specific methods in it, and add that to all your various classes. As long as they properly implement the methods that you define in the Interface you can access them by casting many and varied objects to the type of the Interface. If you put those methods into the interface rather than a super class then it doesn’t matter what they super class is, you could have web containers, web pages, popup windows, whatever and they would all cast to the interface to let you access the specific methods.

    I can’t find a reasonable article on it in the online docs for Xojo, but it’s basically like a super class definition where you spell out which methods it must implement. Any class or object that implements those methods can be setup to have that class interface and be cast to the interface rather than their real parent. It’s extremely useful that way as the super classes do not have to be the same!

  9. Stephen P

    Apr 24 Pre-Release Testers, Xojo Pro

    Thanks James.

    I'm slowly learning about interfaces. Not quite there with them yet. Will look for some exampkes as use cases are always tge best way to learn for me.

    Steve

or Sign Up to reply!