Querying Winforms with LINQ by ThinqLinq

Querying Winforms with LINQ

A couple of months ago, someone asked on one of the forums how you could dynamically switch a control from a textbox to a label based on the editability of the record based on business requirements. The best solution was to change properties on the textboxes to make them look like labels. Below is a quick method to do this:

Private Sub SwitchControl(ByVal box As TextBox)
If box.ReadOnly Then
box.BorderStyle = BorderStyle.Fixed3D
Else
box.BorderStyle = BorderStyle.None
End If
box.ReadOnly = Not box.ReadOnly
End Sub

From here, we need to process all of the controls to make this change to the textboxes (but skip the other controls as they may not implement some of the methods used here, particularly .ReadOnly. Thus the standard code would do something like the following:

For Each ctl As Control In Me.Controls
If TypeOf ctl Is TextBox Then
SwitchControl(DirectCast(ctl, TextBox))
End If
Next

The question was recently raised if you can query the actual page model with winform development using LINQ. This can be done with the MAY CTP of LINQ by leveraging the Cast and OfType extension methods as follows:

Dim textboxes As IEnumerable(Of TextBox) = _
From c In Me.Controls.Cast(Of Control).OfType(Of TextBox)() _
Select c

For Each box As TextBox In textboxes
SwitchControl(box)
Next

In the LINQ example, we need to do a bit of extra casting (using Cast<T> because the ControlCollection class does not directly implement IEnumerable<T>. Once we have it converted into the generic enumerator, we can apply the rest of the standard query operators. In this case, instead of using "Where TypeOf c Is TextBox", we can leverage the .OfType<T> extension method to only yield the controls which we want to manipulate. Note in the LINQ example, we don't have to worry about the cast during the iteration as we have already done it in the generics before.

For those of you who are interested, I did some simple performance testing using a form with 100 textboxes and 30 checkboxes. Both methods performed equally as well. I did not see any significant performance difference between the two methods. That being the case, choosing which mechanism you would want to use would be up to your personal preference. I do suspect that if the ControlCollection natively supported IEnumerable(of Control), the LINQ version would outperform the older machismo due to the ability to leverage the generic support and avoid the casting. This is a relatively simple implementation, but hopefully helps to demonstrate some different functionality you might not have thought of using which LINQ allows.

Posted on - Comment
Categories: VB - LINQ -
comments powered by Disqus