Now I want to customise the BevelButton, so that I can add some other properties, methods, etc.
So I create a Class called AppMenuButton, Super = BevelButton
In the Class I then add Event Handlers > MouseEnter
and then change the Super of the BevelButton on the Window to AppMenuButton
The above code will not compile.
Error :
This item does not exist
TooltipTimer1.Period = ToolTipDelay
So I try :
me.TooltipTimer1.Period = ToolTipDelay
error :
Type "AppMenuButton" has no member named "TooltipTimer1"
and then try :
self.TooltipTimer1.Period = ToolTipDelay
error :
Type "AppMenuButton" has no member named "TooltipTimer1"
self.Window.TooltipTimer1.Period = ToolTipDelay
error :
Type "Window" has no member named "TooltipTimer1"
So what am I missing, or is not just not possible for an instance of a button to set the properties of a timer on the window where the instance exists ?
Your BevelButton subclass doesn’t know anything about the window it lives on. In the constructor you need to add a parameter for the window. Then a property for the window.
Now the timer is a bit more complicated. Hunt something down that is called “Delegating Timer”. This should be mentioned here on the forum a couple of times. Add this to your project. Now you can instantiate your timer in code and add the functionality for it.
If you have any problems then make an example and post it.
[quote=186561:@Dave OBrien]Thank You for the reply.
So are you saying that I should :
add a property to the button subclass, let’s call it ‘OwnerHandle’
when adding the instance of the button to the window, set the instances OwnerHandle property as the Windows handle.
use OwnerHandle.TooltipTimer1 to activate the timer.[/quote]
Is the code in the class, or in the instance ? The class won’t be able to see the timer on the window.
What you may want to do, if you want to use a timer from the CustomBevelButton class, is to add a Timer property to the class, let us call it ToolTipTimer, then
Add a method called ToolTipTimerAction :
Sub ToolTipTimerAction(Sender as Timer)
msgbox "Picaboo" // Whatever you need done
Sender.enabled = False
End Sub
In the class Open :
Sub Open()
ToolTipTimer = New Timer
AddHandler ToolTipTimer.Action, AddressOf ToolTipTimerAction
End Sub
In MouseEnter :
Sub MouseEnter()
dim ToolTipDelay as integer = 1000
TooltipTimer.Period = ToolTipDelay
TooltipTimer.Mode = Timer.ModeSingle
ToolTipTimer.enabled = True
End Sub
In Close :
Sub Close()
RemoveHandler ToolTipTimer.Action, AddressOf ToolTipTimerAction
End Sub
OK. So it looks like coding in subclasses of controls, like a button, is basically limited to interacting with itself only, and for receiving properties from the window that creates the instance.
There is no real simple way of passing info / data / results / setting properties back to the ‘owner’ window from the instance of the button ( meaning from code in the subclass of the button before an instance is created ).
So if I want to have a subclass of a button that changes backcolor when the mouse moves over it, it is coded in the subclass before the instance.
But if I want to interact with the other components of the window that created the instance of the button ( like the timer ), it is best done in the code of the created instance that is on the window.
Does that sound about correct ?
Now I am starting to think that the subclass code for the instance of the button could change a global variable, and the timer could be checking that global variable to do the required actions. So the timer runs every second, but does not do anything until the button has ‘populated’ the activation variable.
[quote=186566:@Dave OBrien]OK. So it looks like coding in subclasses of controls, like a button, is basically limited to interacting with itself only, and for receiving properties from the window that creates the instance.
There is no real simple way of passing info / data / results / setting properties back to the ‘owner’ window from the instance of the button ( meaning from code in the subclass of the button before an instance is created ).
So if I want to have a subclass of a button that changes backcolor when the mouse moves over it, it is coded in the subclass before the instance.
But if I want to interact with the other components of the window that created the instance of the button ( like the timer ), it is best done in the code of the created instance that is on the window.
Does that sound about correct ?[/quote]
The class (CustomBevelButton) basically does not have any reference to the window. In fact, it is in limbo and does not get into existence until an instance materializes it.
Changing backcolor is as simple as me.backcolor = &cFF0000
But if you want to interact with other controls on the window, it should be done in the instance event handler.
If you want to use the MouseEnter event in both the class and the instance, add a MouseEnter event definition to the class, and in its MouseEnter Event, place :
If every occurrence of your subclassed button will end up on the same window and you know which window, you can call items of that window from the event handlers defined in your button.
[quote=186575:@Eli Ott]Use the Window property of the BevelButton and cast it to the window class you have created the timer:
Window1(Self.Window).Timer…[/quote]
Thank You Eli
This worked perfectly in the code in the subclass of the button.
When the instance is created on the Window, it activates the timer exactly as required. So it does only need coding once in the subclass, and works in all instances … only restriction seems to be that coder must know then name of the window ( Window1 ) that the timer and button instances exist on - in this case I do, so it is a perfect solution.
Thanks again and also Thanks to everyone for their input. I have learnt loads again
Well, this is not really a restriction as you need to somehow check if the window has a timer. There are several possibilities:
Wrap everything in your BevelButton subclass related to the timer in If … Then tests:
If Self.Window IsA Window1 Then
Window1(Self.Window).Timer1.Enabled = False
...
End
Or you could loop over all controls of the window to check if one is a timer. This will only work if the timer has been added to the window in the window editor (so it was added as a control). Note that this is independent of the kind of window, it works with any window, not only Window1:
For i As Integer = 0 To Self.Window.ControlCount - 1
If Self.Window.Control(i) IsA Timer Then
Dim t As Timer = Timer(Self.Window.Control(i))
t.Enabled = False
...
Exit For i
End
Next
Or you could use introspection to access the timer, for example should the timer be a property and not a control on the window.