[RESOLVED] Question on implementing/using control extensions
Okay, I have a question. I understand how to build user and composite controls, and how to add them to the toolbox and use them at runtime and design time. What I'm working with, for the first time, is a control extension. I need to create a minor modification to the standard .NET label control... I want to extend the class to add a property and the new functionality based upon that property. I can do that by making a class and inheriting from Label, then adding my new functionality, but once it's written, how do I use it in my applications?
So, how do I make and use a control extension?
Re: Question on implementing/using control extensions
Are you talking about creating a control library that contains the inherited control as well as other custom controls?
If so then you create a control library VB.NET project and write your inherited control in that.
Use namespaces to organize the classes. Compile and save the project.
Add a reference from your new library to any new project when you want to use it.
The free VB.NET Express does not come with a control Library Project Template, but you can use the 'Class Library Template' to do the same thing.
Does that answer your question?
Re: Question on implementing/using control extensions
What do you want to actually do...
Re: Question on implementing/using control extensions
Okay, more details.
I currently have a windows form control library that contains several user controls... they work fine and show up in the Toolbox quite nicely. This I know how to do.
What I want to do now is create, not brand-new user or composite controls, but extensions on the standard .NET controls that can be used.
For a simple example, I want to modify the label class by adding an integer property called "TimeLimit". At run-time, if that value is filled with a non-zero value, the label text should be cleared when the specified time limit expires. (I'll handle it with a little more finesse than that, but that's it in a nutshell.) In several places in my code I use status messages that display for a few seconds and then go away, and I want to extend the label control to automate that functionality.
Like I said, I'm clear on what I want it to do. What I DON'T know is how to extend the label control. Syntactically. (Once I figure that one out, I can figure out the rest of what I want to accomplish.) By that, I mean how do I write the code that will add the desired functionality to the label control? And once that's done, do I have to do anything special (besides linking the control library to my GUI app) to use the new functionality?
I've looked for tutorials online, but haven't found anything that seems on point. Any help is appreciated.
Re: Question on implementing/using control extensions
You are pretty much talking about adding a timed event to a label yes....
Re: Question on implementing/using control extensions
Yes,
You start a new class and just under the class name you use the keywords
'Inherits Label'.
Whatever properties, procedures and events you add to it extends what it can do.
Since you are not overriding any of the label's features the syntax should be straight forward.
Code:
Public Class TimedLabel
Inherits Label
Private WithEvents LabelTimer As New Timer
Public Property Interval() As Integer
Get
Return LabelTimer.Interval
End Get
Set(value As Integer)
LabelTimer.Interval = value
End Set
End Property
Public Sub Start()
LabelTimer.Start()
End Sub
Public Sub [Stop]()
LabelTimer.Stop()
End Sub
Private Sub LabelTimer_Tick(sender As System.Object, e As System.EventArgs) Handles LabelTimer.Tick
LabelTimer.Stop()
Me.Text = ""
End Sub
End Class
' In use
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
With TimedLabel1
.Text = "This is Message to be shown for five seconds"
.Interval = 5000
.Start()
End With
End Sub
End Class
Re: Question on implementing/using control extensions
Thanks for the code, Gruff, I'll take a look at it and compare it to what I managed to work up on my own.
What I ended up with was an extension class that looks like this:
Code:
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
Public Class Form1
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Close()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Label1.Text = "This label will fade after 3 seconds."
'Label2.Text = "This label will fade after 5 seconds."
Label1.ShowFadeText("This label will fade after 3 seconds.", 3)
Label2.ShowFadeText("This label will fade after 5 seconds.", 5)
End Sub
End Class
Module LabelExtensions
Dim WithEvents tmr As Timer
<Extension()>
Public Sub ShowFadeText(ByVal lbl As Label, ByVal text As String, ByVal seconds As Integer)
lbl.Text = text
lbl.Visible = True
tmr = New Timer()
tmr.Interval = seconds * 1000
tmr.Tag = lbl
AddHandler tmr.Tick, New EventHandler(AddressOf Timer_Clock_Tick)
tmr.Start()
End Sub
Private Sub Timer_Clock_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim lclTmr As Timer = DirectCast(sender, Timer)
Dim lbl As Label = DirectCast(lclTmr.Tag, Label)
lbl.Text = ""
lclTmr.Stop()
End Sub
End Module
It wasn't quite what I wanted, but it was the way I had found to get it done, and it does seem to work. It works with a call to a ShowFadeText method instead of simply modifying the existing functionality. I'll have to compare this with what you posted.
Re: Question on implementing/using control extensions
I apologize. Extensions appears to be something I missed entirely when upgrading to 2010.
I have some reading to do.
I could be wrong but this strikes me as a great way to make difficult to find errors.
Re: Question on implementing/using control extensions
Gruff, question on your code.
As I read it, you're creating a new label control based upon the original label control... which was my original thought. Can this control be placed in the toolbox and dropped onto a form in the designer? If so, how? Or can it only be created in the code? If I'm going to create a new control, I want it available in the form designer.
And thanks to Gruff and Edgemeal for their help.
Re: Question on implementing/using control extensions
When I develop an inherited control I use a standard winforms project with a single form.
I add a new class document to the project and develop my inherited control in it.
If you build the project the class will automatically be added to your controls toolbox.
after that you can select it in the toolbox and draw it on the form.
Be sure to delete if from the form if you go back to edit the class as it is possible to trash your form with a bad control.
rebuild and draw it on your form to test again.
When you have a bullet proof control save the project. Close it and start a new Class Library project. Save it so that the project folder structure is created. Copy the inherited control file (Class) from the test project into your Class library project folder.
Use 'Add existing' to load the inherited control into your Class library. Build and close.
You can now create a reference from the compiled class library to any new winforms project.
In the new project right click in your toolbox and select 'Choose Item'. Path your way to the compiled class library and select it.
Your inherited control should show up in your toolbox.
I am sure there is a better way to develop the control. This is just the way I prefer.
Standard Controls, Composite UserControls, and Inherited Controls are all very useful, however if you want to completely control your graphics sometimes the only way is to inherit a usercontrol and build the entire thing from scratch.
Re: Question on implementing/using control extensions
Thanks, Gruff... just got finished doing it your way and it works fine. The extension method I came up with works, mind you, but this is more in line with what I wanted in the first place. Thanks!