views:

316

answers:

6

I am working on a Windows Forms app for quite some time now, and I really find myself doing more typecasts in the GUI code than I ever did in my underlying business code.

What I mean becomes apparent if you watch the ComboBox control that accepts some vague "object" as it's item. Then you go off and may display some DisplayMember and a ValueMember and so on.

If I want to retrieve that value later I need to typecast my object back to what it was. Like with strings getting the value takes

string value = (string)combobox1.SelectedItem;

Since there are generics in the Framework for quite some time now, I still wonder why in the Hell not one control from the standard toolbox is generic.

I also find myself using the .Tag property on ListViewItems all the time to keep the displayed domain object. But everytime I need to access that object I then need another typecast.

Why cant I just create a ComboBox or ListView with items of type ListViewItem

Am I missing something here or is this just another example of not perfectly well thought through controls?

+1  A: 

I dont think you're missing anything. It's just that these classes were created back in the pre-Generics days, and WinForms is simply not cutting edge enough for MS to spend a lot of time changing or extending the API.

mackenir
+1  A: 

I often create wrapper classes for controls. This allows me to use generics. This is often in conjunction with Reflection, which is not type safe at compile time, but can be at run time.

eulerfx
+3  A: 

While the criticism of "didn't use generics" can't be fairly applied to controls developed before their existence... one must wonder about WPF controls (new in .NET 3.0, after generics in .NET 2.0).

I checked out the AddChild method in ComboBox. It takes an object parameter (ugh).

This control is intended to be used primarily via XAML. Was this done this way because there is no way to specify a type parameter in XAML? (aside, is there no way to specify a type parameter in XAML?)

Sorry to have no definitive "Why" answer, just sharing the common misery of needing to cast when working with the UI.

David B
+1  A: 

A common source of this problem, I think, is not separating your view/presentation logic from your in-memory data model logic. Which, unfortunately, is an architecture fault that WinForms and the Visual Studio GUI designer are complicit in.

WinForms and the VS designer do not encourage the programmer to separate the management of their data objects from the form classes themselves. It would probably be better if the ComboBox ListViewItem objects didn't offer any support for arbitrary objects, either via generics or Object collections..

Unless you are hacking together something of limited use and lifetime, you should try to avoid storing references to individual data objects right in your controls or forms. They should be managed separately, and if they need to be referenced, it should be done via a model management class designed for the particular type of view class you're working with.

A simple-ish bandage for the problem, though, might be to "map" the text representations that you place into the ComboBox or ListView to the original objects, using a Dictionary field member on your Form class. It's not an ideal solution, but gives you at least a half-step of indirection between your data and your UI controls, which can make your code easier to maintain.

Edit: This is admittedly separate from the ListViewItemCollection class exposing Object instances... The official defense is likely to be that they wanted to support the standard IEnumerable and ICollection interfaces. But there's no reason they couldn't have also provided type-specific overrides of these methods, since it is designed explicitly to store ListViewItem instances. So I have no answer for you on that particular question.

Chris Ammerman
+1  A: 

Well, if you data-bind your controls to a DataBindingSource, you can get at your data that way, but AFAIK that's still not strongly typed. If you are displaying multiple parameters/aspects of a single business object, you can bind to that, then access the (strongly typed) members instead -- of course, this all goes back to Turbulent Intellect's answer, which is better separation between model and view. Still, I agree that generic-based typing would help.

Coderer
+1  A: 

It is possible (you can make your own generic controls, if you wish), but the form designer that comes with Visual Studio will freak out if you do this. You'll have to do stuff without it.

You aren't the first one to think of this, and Microsoft has already received a fair share of criticism from the public for this. Let's hope they add support for this in the future.

Vilx-