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.
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…
[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…
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"
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
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
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…
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
create a new desktop project
create a new container - name it myContainer
add a method to myContainer - foo()
drag an instance onto the default window in a desktop project (the one named Window1)
add the OPEN event to Window1
in there put
myContainer.foo()
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
create a local variable to refer to the dialog (dim myDialog as new WhateverDialogType)
show the dialog modally etc
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
create a new desktop app
add a new window and set its frame type to “movable modal” name it “myDialog”
add two buttons and label one “cancel” and one “close”
add a property “cancelled as boolean” and make sure it is public
add the action event to the cancel button
in there add
cancelled = true
self.close
add a textfield name “userText” (so the user can enter something and we can send it back to the caller just to illustrate)
add another property “userEnteredText as string”
in the “close” button add this code to its action event
userEnteredText = userText.text
self.close
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
now on Window1 add a button and a text field - name the text field “fromDialog”
add the action event to the button
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