Item doesn't exist on the same window error

I am trying to get a button’s enabled status from false to true when I type in a text field, which is normally easy enough when the text field and button are both on the WinMain window.

However I cannot get it to work on another window even though the button is being found while referring to it in the TextChanged Event Handler.

This is the code in the text field on the separate Window (WinHeroActionHeroQuestions) in the TextChanged Event Handler:
WinHeroActionHeroQuestions.btnUpdateActionHeroQuestions.Enabled = true

there are two ways for windows:
a single instance where you use just the windows name.
or you would create a new object, you must store it somewhere to access it.

Or use Self to refer to the window the textfield, and presumably, the button is on.

Self.btnUpdateActionHeroQuestions.Enabled = true
1 Like

I tried that, but the Self. reference would not work in this case because the text field is placed inside a Container which is placed on the window.

So you need to drill down into the container, such as

Self.Container1.btnUpdateActionHeroQuestions.Enabled = true

But the more OOP way would be to put a Method on the container and call that, rather than using the button name directly. Something like

Self.Container1.EnableHeroQuestions(True)

That would decouple the button and allow you to change it from a button to something else like a radiobutton or even a textfield without changing the window code. Only change the container implementation of the method.

I’m not suggesting you do that in this case, but just pointing out there is a more generic pattern for dealing with container controls. Generally, you treat a container as a black box. The less the window needs to know about the container the better. The window addresses the container by calling reasonably named methods on it. The container communicates to the window by raising events. That way, the UI of the container is encapsulated in the container and the window doesn’t need to be aware of the details. You are free to change those details as you please without changing the window code.

But for your purposes, just address the container and then its contents.

1 Like

Thanks, I will give this a try. It’s getting complicated now when trying to find the right paths when working with other windows and containers. Time to write things down on paper :slight_smile:

That part is the first thing to do…

In French:
Spécification Technique de Besoin

There is a better page, and it exists also in english, but where ?

1 Like

If it’s getting complicated then you need to make things more simple. My rule is to have all controls private. This forces me to define how the windows and the containers communicate. The windows and containers should communicate back to the controller which then gives the information back to the windows/containers. Anything else will end up in a huge mess.

A container is very ‘like’ a window
Using self. means ‘this container.’

To refer to the window on which the container has been placed, you need to talk to the parent of the container

WinHeroActionHeroQuestions(self.parent).btnUpdateActionHeroQuestions.Enabled = true

In any case
WinHeroActionHeroQuestions.btnUpdateActionHeroQuestions.Enabled = true

assumes that there is one and only one WinHeroActionHeroQuestions window, and that it is called WinHeroActionHeroQuestions

Sometimes people will create a ‘new’ window, called (eg) ThisWindow
If you do that, there will be no WinHeroActionHeroQuestions to refer to.

One thing I have done in the past is to have references to each window held as a global property in a module.

eg


theActionHero as  WinHeroActionHeroQuestions

When the window opens , set that value …

theActionHero = self

Now, if you followed that, the code to disable the button can be this, used anywhere in your app… container, window, app, anywhere

theActionHero.btnUpdateActionHeroQuestions.Enabled = true

1 Like

Thanks! It took me a while to digest, but I got it to work!