Dynamic Casting With Generics... Examples in VB.NET and C#

By Andrew D Green

This is a solution I came up with to handle the issue of dynamic casting of controls. In this case I had a situation where I needed to be able to specify a control or form parent control collection and the name of the control I wanted to emulate and access the properties of. I wanted to be able to use a dynamic object to access the properties of an object embedded within a form without having to hard code any specific values associated to identifying that control.

Here's the actual class that implements the generic type that I will use to cast a located control from. The generic variable is itemType. I loop through the parent collection of controls and locate the control I seek to emulate as a Control type. Once found, perform a DirectCast to cast from Control type to the generic itemType. The function then returns the itemType specified in the object instantiation :

VB.NET
Public Class NewGenericControl(Of itemType As {Control, New})

Public Sub New()

End Sub


Public Function GetControlByName(ByVal controls As Control.ControlCollection, ByVal ctlName As String) As itemType
Dim newCtl As New itemType
' Loop trhough the controls on the parent to locate the desired control to manage
For Each ctl As Control In controls
If (ctl.Name.StartsWith(ctlName)) Then
newCtl = DirectCast(ctl, itemType)
Return newCtl
End If
Next ctl

Return newCtl

End Function


End Class


C#
public class NewGenericControl<itemType> where itemType : Control, new() 
{

public NewGenericControl()
{

}


public itemType GetControlByName(Control.ControlCollection controls, string ctlName)
{
itemType newCtl = new itemType();
// Loop trhough the controls on the parent to locate the desired control to manage
foreach (Control ctl in controls) {
if ((ctl.Name.StartsWith(ctlName))) {
newCtl = (itemType)ctl;
return newCtl;
}
}


return newCtl;
}


}


Here's the code that accesses the class by specifying a control type. It's only two lines of code. In this case I am emulating a PictureBox that I used to act as a button. As you can see, I'm accessing the Enabled property of the control itself through the generic instance of the control:

VB.NET


Dim newCtl As New NewGenericControl(Of PictureBox)()

newCtl.GetControlByName(m_parent.Controls, "btnNext").Enabled = True



C#


NewGenericControl<PictureBox> newCtl = new NewGenericControl<PictureBox>();

newCtl.GetControlByName(m_parent.Controls, "btnNext").Enabled = true;



Here's another example with a TreeView control that was embedded in a SplitContainer panel control inside the form:

VB.NET

Dim splitContainer As New NewGenericControl(Of SplitContainer)
Dim newTree As New NewGenericControl(Of TreeView)

newTree.GetControlByName(DirectCast(splitContainer.GetControlByName(m_parent.ParentForm.Controls, "SplitContainer1").Panel1, Control).Controls, "treeAnswerList").Nodes(Me.QuestionId).Nodes.Add(1, m_answerValue)


C#

NewGenericControl<SplitContainer> splitContainer = new NewGenericControl<SplitContainer>();
NewGenericControl<TreeView> newTree = new NewGenericControl<TreeView>();

newTree.GetControlByName(((Control)splitContainer.GetControlByName(m_parent.ParentForm.Controls, "SplitContainer1").Panel1).Controls, "treeAnswerList").Nodes(this.QuestionId).Nodes.Add(1, m_answerValue);



As you can see you can directly access embedded controls even by passing in an emulated instance of the parent container control! Sweet...