Stash Data Away in Controls With the Tag Property Using VB.NET

Tagging ObjectsOne of the most underutilized properties of any control is a property called “tag”. What does it do? Does it cure world hunger? Does it save the planet from annihilation? I would probably say no on both counts, but it does have a bit of a mystique that beginners may not be fully aware of. In design mode of Visual Studio if you select a control, a button or text box or picturebox etc, you will see the property listed in the properties window. The IDE only gives a vague description of the property saying “User-defined data associated with the object”. That is fine and dandy, but what kind of data and how do I use this property?

A little history about this property may help. Back in the early days of VB (I am thinking VB6 specifically) this tag was simply a string property for just misc text data. With .NET they made it into a full object. I guess it was real popular so it was carried along. Frankly I am glad they did. It is a time saver in some situations.

An example of how it works

Anyway, the best way to explain this property is to use an example. We are thinking of making a picture editing application and decided that we are going to use a picturebox to display each picture we open up. So we drag a picturebox control onto our form and start wiring it up for displaying pictures. As part of our application we want to be able to also display some misc data about the picture we are showing. Where was it taken? Perhaps we want to quickly store away the dimensions for later use in our application. Maybe we want to attach a temporary note to the picture while it is in the picturebox control without having to dig into the image itself. All reasonable things to ask for. This additional data, or meta data as we will call it, is a perfect scenario for our tag property to handle.

If you have seen this tag in use already, you might have seen it using a fraction of what it is capable of. Most people like to store a simple string into it. But you will notice the tag accepts an object. Since everything we create in .NET is an object, this could be one already defined by the framework or one created by us. This means we could create something like a settings object which stores any data we want and then stash it away into this tag.

The only thing we have to remember is that when we stash away an object into this tag it is stored as an object. Meaning if we want to use it as our original object we will need to change it back after we retrieve it. Lets show an example of that using some VB.NET…

' Start by creating a custom structure with some of the properties

Private Structure ImageInfo
    Public Property Filename As String
    Public Property Width As Integer
    Public Property Height As Integer
    Public Property Note As String
End Structure


' With a click of button 1 we are going to create an ImageInfo object
' Then populate it with data about our image and set the picturebox.tag
' property to this object.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim info As New ImageInfo

    ' Set some properties of our image
    info.Filename = "Some_File.png"
    info.Width = 100
    info.Height = 300
    info.Note = "Some misc text about 'Some_File.png' that we want to keep track of."

    ' Put it away into the picturebox control's tag property
    PictureBox1.Tag = info
End Sub


' Button 2 will then pull out that data, convert it back to our object
' then display the notes about the object.

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click

    ' Note how we convert this type back from 'Object' to Imageinfo
    Dim ourInfoObj As ImageInfo = CType(PictureBox1.Tag, ImageInfo)

    MessageBox.Show("Filename: " & ourInfoObj.Filename & " Dimensions: " & ourInfoObj.Width & " x " & ourInfoObj.Height & " Note: " & ourInfoObj.Note)
End Sub

Skies the limit

This is a very simple example but demonstrates what is possible with this property. This property can save us some time of having to recalculate some values that, with images especially, can be CPU intensive. The fact that we can create the type of object for the tag means that we can store complex objects with methods, properties events etc and then get at them at some later time. They are part of the control. This info travels with the control and could be set for objects that are part of a list, controls dynamically created, maybe even another control with a different state. Your imagination is the limit really.

I hope you found this tidbit of information useful and remember, don’t abuse this property. Not everyone is going to know to look in a tag property for data. So use it sparingly and if you can make everything about an object as explicit as you can for good maintainability. Thanks for reading! :)

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebook "The Programmers Idea Book". He has been a programmer for over 17 years. He works for a hot application development company in Vancouver Canada which service some of the biggest telecoms in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.
  • Jeremy

    What if someone comes in to maintain the software and doesn’t know the data is in the tag property? Your tag suggestion is an awful solution.

    Wouldn’t it be simpler if you need to store this stuff to make a class with 1 additional property and then just inherit the control that you want to have such a property? That is the whole point of .net. You then avoid the type casting.

    Public Class ImageInfoButton
    Inherits Button

    Public Property ImageInformation As ImageInfo

    End Class

    Why not use generics even to make a button that accepts any type as the custom property type? That way you avoid Object->T casts.

    Jeremy Child.

    • http://www.coderslexicon.com Martyr2

      Actually if someone comes in to maintain the code they will most often than not see you storing the object. But you are right, there is a chance that someone may miss it. The idea behind the tag property is that whoever put content in it would also be pulling it out and using it. Remember, this isn’t often just a one liner but probably a whole function to store and retrieve.

      And if you are going to store anything of any significance, by all means do create a class for it explicitly. However I do think you solution is a bit more work than it needs to be for something like this.

      The tag property is a quick carry-over solution from earlier days of the language and is handy as a shortcut storage solution that follows the control itself. No need to inherit, no need to build some generics etc. A quick stash and go solution.

      But certainly if you are going to create a terribly complex object, most definitely make it explicit and in the programmers face. Thanks for the comment! :)