Home > Articles > Programming > Windows Programming

  • Print
  • + Share This
From the author of

Testing the Attribute

Any time we write code, it's a good idea to test it. For this test, I implemented a Customer class that uses the custom attribute and a simple generator that reads the attributes if they exist on a type. The generator uses the attributes as a guide to create a basic Windows user interface.

Listing 6 contains the code that demonstrates applying the attribute, and Listing 7 shows a very basic generator that will read the attributes and generate Windows Forms controls.

Listing 6—Applying the ControlDesignerAttribute Custom Attribute

Public Class Customer

 <ControlDesigner( _
  "System.Windows.Forms.TextBox, System.Windows.Forms,
[ccc]Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", _
  Caption:="Name", _
  LabelName:="System.Windows.Forms.Label, System.Windows.Forms,
[ccc]Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", _
  X:=0, Y:=10, Width:=100, Height:=20)> _
 Public Property Name() As String
 Get

 End Get
 Set(ByVal Value As String)

 End Set
 End Property

 <ControlDesigner( _
  "System.Windows.Forms.TextBox, System.Windows.Forms,
[ccc]Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", _
  Caption:="Phone Number", _
  LabelName:="System.Windows.Forms.Label, System.Windows.Forms,
[ccc]Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", _
  ValidationExpression:="^(\d\d\d) \d\d\d-\d\d\d\d$", _
  X:=10, Y:=50, Width:=100, Height:=20)> _
 Public Property PhoneNumber() As String
 Get

 End Get
 Set(ByVal Value As String)

 End Set
 End Property
End Class

The application of the attribute as defined looks a bit daunting. If I were building a commercial application, I would probably generalize the ControlDesignerAttribute as a series of simpler attributes that provide basic arguments for text boxes, labels, check boxes, etc. to the ControlDesignerAttribute. I would probably revise the custom attribute to use a Type record too.

Listing 7—Using Reflection to Read the Custom Attributes and Generate Controls

Public Class FormDesigner

 Public Shared Sub Generator( _
  ByVal Parent As Control, ByVal Type As Type)

  Dim [Property] As PropertyInfo
  For Each [Property] In Type.GetProperties()
   GenerateControl(Parent, [Property])
  Next

 End Sub

 Public Shared Sub GenerateControl(ByVal Parent As Control, _
  ByVal [Property] As PropertyInfo)

  Dim Attributes() As Attribute = _
   [Property].GetCustomAttributes( _
    GetType(MyAttribute.ControlDesignerAttribute), True)

  If (Attributes Is Nothing) Then Exit Sub

  Dim A As Attribute
  For Each A In Attributes
   CreateControl(Parent, CType(A, ControlDesignerAttribute))
  Next

 End Sub

 Public Shared Sub CreateControl(ByVal Parent As Control, _
  ByVal Attribute As ControlDesignerAttribute)

  Dim Label As Control = _
   Activator.CreateInstance(Type.GetType(Attribute.LabelName))
  Label.Text = Attribute.Caption
  Label.SetBounds(Attribute.X, Attribute.Y, _
   Attribute.Width, Attribute.Height)


  Dim Control As Control = _
   Activator.CreateInstance(Type.GetType(Attribute.ControlName))
  Control.SetBounds(Attribute.X + Attribute.Width, _
   Attribute.Y, Attribute.Width, Attribute.Height)

  Parent.Controls.Add(Label)
  Parent.Controls.Add(Control)
 End Sub

End Class

I've provided only a basic generator, to show you that it could be done with moderately low difficulty. The code uses reflection to discover the attribute values and from there generates controls.

If you're unfamiliar with how reflection works in .NET, I encourage you to pick up a copy of my Visual Basic .NET Unleashed (Sams, 2002, ISBN 0-672-32234-X), or a comparable book by your favorite author. (Tell them Paul sent you.)

  • + Share This
  • 🔖 Save To Your Account