Containers - Static Reference to Instance Method Error

I have a bunch of containers that I have drug onto pagepanel pages…

One container, I have reused by dragging it onto another modal window as well.
That container has a button on it that is only visible if the container is being shown in that specific modal.

When someone clicks that button, I have properties that are global that have values set.
I can access to values from anywhere, which is fine.

But the container that I launch the modal from, when the window is closed, I try to update a label’s text on that container with the value from a property.

When I do it, I get the error:

Static reference to instance method: call this on an instance of class…

This is driving me nuts… I am missing something somewhere.

Code ?

Well… not sure what I can really put on here to show it… trying not to show the actual application here… let me see if I can put something here in a more visible way… or recreate it in an example…

Will update this post here in a few…

Check over your code for places where you’ve got ContainerControl when you mean (or it should be) ContainerControl1

[quote=326420:@Don VF]Well… not sure what I can really put on here to show it… trying not to show the actual application here… let me see if I can put something here in a more visible way… or recreate it in an example…

Will update this post here in a few…[/quote]

It is difficult to help with nothing to go on.

I recreated my issue in another quick application:

Video

And the code for the example:

Project File

Pretty sure this has to be something completely stupid on my part.

On the container superclass (the one you edit) you don’t reference the container instance (the one on the window).

The button’s code inside the container should be Label1.text = "aoidufalsdfj" instead.
If it was on the window next to the container it would be ContainerControl1.Label1.text = "afdasdfasdfa"

I had to do: Window1.container1.Label1.Text = “kjhakjhakjshdkjahskdjhakjsdh”

Unfortunately that still isn’t fixing my issue in the actual app I am working on… but in that example the above line worked… uggghhh

@Tim Parnell

Actually sent you a private message on it, since you have seen the code before. :wink:

make an API on your containers so you DON’T have to reach inside them an manipulate their contents

on the original container - not the one on the layout - add a method “SetLabel(s as string)”
in that method then take the text and put it where it belongs

that way your code becomes more self contained and your objects more reusable and simpler to maintain
instead of code that requires you know the guts intimately like

Window1.container1.Label1.Text = "kjhakjhakjshdkjahskdjhakjsdh"

you do

Window1.container1.SetLabe( "kjhakjhakjshdkjahskdjhakjsdh" )

Yes it looks a lot “the same”
Suppose you change your mind and want to make Label1 a canvas instead ?
In the old style you have how many places to update ? At least as many places as you wrote that old style code (and right now that may be a handful but ins something the size of the IDE this could be a real problem)

If you do like I’m recommending you have 1 place to update - that “set method”

The end goal is to make it so you design “black boxes” where even though you could just reach into the guts you don’t because that leads you into a hard to maintain way of working

As a “for instance” the ENTIE inspector is a scrollable set of containers - and each “style” of inspector pane is a container (ie/ there’s one for switches, one for control locking, one for editing interfaces on an object, etc - nearly EVERY row is one pane)
And thye all have a common API so manipulating each one does not require knowing each ones internals intimately
It means we can literally say “give me an editor for a property of Type X. set it up with this property” and be done
Everything else works identically across them
The inspector would be impossible to deal with if we had to manipulate the innards of each one specially OR specifically like your code is doing

@Norman Palardy

I still must be missing something…, because what your saying here, I actually was trying as well… As far as making a method that was called instead of directly changing the value.

In the original container I have a method called: setSitename

For the example here I will call the original container… container.

The instance of that container that I have on another window is called: containerInstance

I actually just went back and set it up like you said though…

So basically container now has a method that is like:

setSitename(s as string)

inside that method I have:

lblSelectedSite.Text = s

So I have a modal window that shows an instance of another container on it, that has a button on it.

When the button is clicked, it sets values for global properties with values form the text fields on that page.
And then it closes that window…

On the close event of the window, I now have…

winMain.containerInstance.setSitename(selectedName)

Property is selectedName that holds the value…

But I still get:

Static Reference to Instance Method: Call this on an instance of class container.container

I have it jury rigged at the moment with a timer checking if the property has a value

that message stems from using the CLASS name instead of an INSTANCE name

say your container is called “myContainer”
and you drag an instance onto a dialog named “myDialog”

the instance on the dialog should be, by default, named “myDialog.myContainer1”

If however you wrote “myDialog.MyContainer” then you get this error because an instance method (ie/ not shared ones) can only be called using an instance

you can replicate this by

  1. create a new desktop project
  2. create a new container - name it myContainer
  3. add a method to myContainer - foo()
  4. drag an instance onto the default window in a desktop project (the one named Window1)
  5. add the OPEN event to Window1
  6. in there put
    myContainer.foo()
  7. run

you should get exactly this error

and this makes sense because the FOO method is only callable using an INSTANCE but we’re trying to use the CLASS to access it and it is NOT callable on a CLASS - hence the error message

I suspect in the close event of the dialog you have this - but in reverse

Often what you see done is

  1. create a local variable to refer to the dialog (dim myDialog as new WhateverDialogType)
  2. show the dialog modally etc
  3. after the close event on the dialog in their main code the DIALOG also have an api so you can ask it for the values the user set

Again - the API on the dialog is a way to insulate yourself from the dialog having to know the innards of the window to return a value to it. The window creates and instance and has aa well defined API to ASK the dialog “so what values did the user chose?” without the dialog having to know the windows innards AND without the window having to know the dialogs innards

ok I can see the next question coming “So how do I do that”

lets demo it in a really small app

  1. create a new desktop app
  2. add a new window and set its frame type to “movable modal” name it “myDialog”
  3. add two buttons and label one “cancel” and one “close”
  4. add a property “cancelled as boolean” and make sure it is public
  5. add the action event to the cancel button
  6. in there add
cancelled = true
self.close
  1. add a textfield name “userText” (so the user can enter something and we can send it back to the caller just to illustrate)
  2. add another property “userEnteredText as string”
  3. in the “close” button add this code to its action event
userEnteredText = userText.text
self.close
  1. turn OFF implicit instance on this new window

cancelled and userEnteredText are the “API” portion of this dialog that the rest of your app uses & cares about

  1. now on Window1 add a button and a text field - name the text field “fromDialog”
  2. add the action event to the button
  3. in the action event put
       dim dlg as new myDialog

       dlg.ShowModal

       if not dlg.Cancelled then
              fromDialog.text = dlg. userEnteredText
       end if

and hit run

try this out & you’ll see that you really DONT want, or need, to ever have to reach inside any other window or class
Make an API you can use and save yourself a lot of headaches