Elaborating on an Earlier Post

I wanted to take a second and defend my earlier post about WindowsForms. Had quite a few people point out how obviously stupid I was for not looking deeper into the system. So, I thought I would take a few minutes and point out what my specific beefs are, coming from the ASP.NET world. Just because I am normally a WebForms developer does not make my arguments any less valid, nor does it mean that this is my first time building a WinForms app. This is my first super-complicated WinForms, and I don't like the hoops that I had to jump through to make it work.

I'm going to start out with the List controls. I'm going to come right out and say it.... they suck. BIG TIME. I'm going to get really specific about why they suck, so bear with me. Lets start with putting items into the collection. In ASP.NET, you get a Name/Value collection. Doesn't matter how you do it, you will always get a SelectedIndex, SelectedText, and a SelectedValue property. Not so with WinForms. In the designer, you get a single line box that says "Please enter one item per line". Further, items are not of an expected type, like ListItem. No, Items are of type Object, which makes the whole control really discoverable IMO. (Please note that the previous statement was sarcasm.)

So then, Cory Smith tells me that the IS documentation and samples for these controls, "Just hit F1, stupid". What Cory and a few others neglected to do when looking at these documentation samples was to actually READ THEM and run the code. Just for a review, here is the code in this sample:

Private Sub WhatIsChecked_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
  Handles WhatIsChecked.Click

  ' Display in a message box all the items that are checked.
  Dim indexChecked
As Integer
  Dim itemChecked As Object
  Const quote As String = """"

  ' First show the index and check state of all selected items.
  For Each indexChecked In CheckedListBox1.CheckedIndices
   
' The indexChecked variable contains the index of the item.
    MessageBox.Show("Index#: " + indexChecked.ToString() + ", is checked. Checked state is:" + _
      CheckedListBox1.GetItemCheckState(indexChecked).ToString() + ".")
  Next

  ' Next show the object title and check state for each item selected.
  For Each itemChecked In CheckedListBox1.CheckedItems
    
' Use the IndexOf method to get the index of an item.
    MessageBox.Show("Item with title: " + quote + itemChecked.ToString() + quote + _
      , is checked. Checked state is: " + _
      CheckedListBox1.GetItemCheckState(CheckedListBox1.Items.IndexOf(itemChecked)).ToString() + ".")
  
Next

End Sub

For Each item As String In CheckedListBox1.CheckedItems
  MsgBox(item)
Next

Pasting this code into VS.NET brings up quite an interesting result. indexChecked.ToString is NOT wired up to actually dump the value to a string. It is actually designed to dump the item type to a string, which seems to me to be rather useless. Now, as I mentioned before, the type is not a variant of ListItem, as you would expect. It's actually a member of System.Data.DataRowView, which is not even CLOSE to being intuitive OR discoverable. Little did I know that I would actually get a database row to work with instead of a name and value, EVEN THOUGH I set a "DisplayMember" and a "ValueMember". I can't even access the value that I set. Further, the last "For...Each" loop produces zero useful information.

OK, onto the different ways to access selected items. I blogged earlier that there were something like 9 different ways to get at a selected item. Several people said that I was incorrect, and they were right. Further inspection of the object model with IntelliSense uncovered 12 different properties that could be used (or a user would assume could be used) to access selected items. They are (in alphabetical order):

CheckedIndexCollection
CheckedIndices
CheckedItems
Items
SelectedIndex
SelectedIndexCollection
SelectedIndices
SelectedItem
SelectedItems
SelectedObjectCollection
SelectionMode
SelectNextControl

I mean, come on here. I thought this stuff was supposed to be intuitive? I can't even have a simple name/value pair. And don't even get me started about databinding. The designer doesn't support specifying column names to bind text and values, instead you get DisplayMember and ValueMember (wtf is that???) and the binding is not procedural (i.e. CheckedListBox.DataBind), it's actually called when you set the DataSource.

Now, this is not just a pointless ranting, so if you're still paying attention, here is the point. It is extremely apparent to me that WinForms is the bastard child of .NET. Don't believe me? Open up two browser windows, and put them side by side. Set the one on the left to www.windowsforms.net, and set the one onthe right to www.asp.net. See the difference? The quality of information and presentation on www.asp.net is dramatically better. This same disparity is apparent in many aspects of WinForms construction, from the samples, to the documentation, to the object model. Is that the fault of the WinForms team? No. It's the fault of Microsoft as a whole, and here is why.

Microsoft touted .NET as the way to build client-independant systems. Using web services back ends, it doesn't matter what front-end you use. Here's the dealmaker/breaker. For this architecture to make sense, and have a wide adoption, both client models should be intuitive, and close enough alike that someone specializing in one client mode should be able to put together the other in a fairly straightforward way. For me, this is not the case. Am I the only one that feels like it? Probably not. But I shouldn't need a CS degree and 4 hours to figure out how to get data in and out of a freakin ComboBox, for BillG's sake!

In closing, I am distressed at the amount of negative activity occurring in this community as of late. I don't know why everyone jumps down everyone else's throat all the time, but calling me an idiot and a moron because I have an opinion is hardly showing respect for anyone as individuals here. We are all examples to others here, and we should behave as such. If my post came across as rude, then I apologize. I think I've spent long enough at this point validating my original argument, and I stand by it. I never said that they didn't do a good job compared to what they had. My problem was with the level of disparity and lack of intuitiveness between the two programming models. And the people at Microsoft should pay attention to that opinion. If a seasoned programmer has difficulty with it, how hard is it going to be for a newbie?

14 Comments

  • Bravo, bravo.

    I worked with Delphi long time before windows forms.

    My opinion: Delphi handles windows application much better when vs.net.

    I just don't understand this: it seems to me Microsoft just don't learn from others.

    While C# obviously taken from java(and improved, I hope) but windows forms programming it is a disaster.

  • Using both WinForms and WebForms, and coming from a C++/Win32 and ASP & JSP background, I disagree with you.



    I'm not going to argue each point here (perhaps I'll blog it?), but I do want to help explain why you're being "jumped on":



    When you say things like "..they suck..", "extremely obvious that this whole WindowsForms thing was not throught out as well as the ASP.NET side was" (previous post), you are making it clear that you consider this to be *fact*, not your opinion.



    When you espouse your opinion in a public arena and present it as though you believe it to be fact, you'll encounter harsh response from those that disagree. Every time.



    So it's really your choice - rant away with your thoughts -- present them as vitriolic absolutes and be prepared for the fire, or present them as well thought-out opinions and start a discussion. But don't berate "the community" when your words have the intended effect.

  • You're right - WinForms sucks in many ways. However, I don't think you've identified anything particularly sucky here.



    First, the WinForms list controls are designed to work with real objects, not strings. Why would I want SelectedItem to return a ListItem if I've bound a collection of Customer objects to it? I want my Customer back, thanks.



    Second, your list of "Select-y" properties is heavily contrived: 3 members of that list are classes, not properties. SelectNextControl just happens to have the word "select" in its title, ditto SelectionMode. The rest form a perfectly symmetrical API for accessing 1) all items, 2) selected items or 3) checked items. The WebForms lists are simpler because *you can't get a list of all selected items*. Instead, you get the lowest item in the list. Did someone say intuitive? I still have nightmares about parts of the ASP.Net API.



    Third, jumping from your brief (negative) experience with the WinForms API to blaming it for third world hunger (or whatever) is quite a stretch. Calm down.



    WinForms is not ASP.Net. It isn't meant to be.

  • Agreed. My partner and I were talking about this just recently. My guess is that Winforms was not thought through because the focus was on ASP.NET and Webforms.



    Wally

  • Sorry to come into your blog and attack you but ...



    "In closing, I am distressed at the amount of negative activity occurring in this community as of late. I don't know why everyone jumps down everyone else's throat all the time, but calling me an idiot and a moron because I have an opinion is hardly showing respect for anyone as individuals here."



    "Gentoo is at it again. Thanks Scoble for a lucid answer. I was getting sick of all the crybabies bellyaching because it's not done yet. It's amazing to me how so many developers in the business know so little about the business of developing.

    Robert McLaws • 3/11/04; 11:56:20 PM"



    Are you the same guy who called all the developers with an opinion about the Whidbey slip crybabies? Now you're complaining about the negativity in the community?

  • I dunno, I just haven't had much trouble working with listboxes. With databinding, set the datasource, displaymember, valuemember, then look at SelectedValue, how hard is that? And I've found it pretty useful to be able to get any object type out of it. Now, if you want to complain, here are imho a couple things to complain about:



    1) Model-View-Controller isn't done right. Bind two listboxes to the same datatable, and when you change one of them it changes the other one too. The pointer to "current record" is in the datatable, not in the listbox.



    In Swing and Cocoa, you can make two controls that point to the same data, and get a different view of common data in each control. That's the way it should be.



    2) There should be a way for events like combobox.SelectedIndexChanged to tell you whether the event was caused by the user or by your code. I don't know enough about Windows to say if this is even possible, but not having it makes for a royal pain when you have multiple controls that are supposed to affect each others' state.

  • I think you still miss the point. Most of the control in Winform are based on their native counterparts. What you don't like is the native win32 listview.



    If you don't want to take the time to try and understand why the native control is the way it is you're simply bashing something without understand it and it doesn’t have much weight. Win development is not web development, it has a legacy and a history and a LOT of people expect things to work in a certain way because that's the way they've been developing on this platform for the last 10 years. An entire industry is built on that knowledge. Legacy is not just a bad thing, consistency is good.



    Trying to map existing knowledge to a new area is helpful but a dangerous task too. In this case more complexity also means more power to the user. And you might have to jump through some of the hoops imposed by win32 but if you think Winform is unnecessarily complex, try ATL... It's complex but some people love it.



    Funny thing is, we get the exact symmetrical argument from people who've been doing client dev for a long time. I've hear people complain that we’ve removed some of the flexibility from the win32 api and they wish Winform would map more of it, making Winform even more complex. Should we alienate our core programmer group because we've completely changed the way they've worked with win32 or should we make it easy for people with no experience? It's a difficult balance.



    In the end I think it comes down to the fact that you say that win32 is too complex and you think that even with the added help from winform the bar is still too high for a lot of people. I see your point but I disagree.

  • Sorry can't stop myself from making another comment.... I never know when to stop :].



    <i>I don't think you should have to have a degree in both worlds to be able to program to it. There ought to be a way that makes it cater to the best of both worlds. And enough of the people here echoed similar complaints that I don't think it can be ignored. </i>



    Well I think nearly everyone agrees with that :) And that's where WinFx comes in. At this point you cannot magically "simplify" win32, it's a gradual process. I think I have addressed why we are where we are today and why it was the best solution, for now, to the problem with the resources and the time frame. Like I said in my first post, WinForm is not about re-inventing client programming, it's about making win32 more easily accessible from the managed world. Re-inventing the client dev is the Longhorn vision and that's also where MS is going. It's not like we're ignoring the input, we are investing huge ressources into this vision but it can't happen overnight as it is a huge undertaking that needs to be rock solid to handle the unavoidable evolution over the next decade. Also, it won't be available on everyone's desktop for quite a while, even after longhorn is released. There is a real need for a bridge here and that's also what WinForm is about.

  • WRT the statement that WinForms is the bastard child of .NET.



    The reason there is less interest in WinForms than WebForms is that:



    - WinForms only provides incremental benefit over the existing mature tools for developing Win32 apps (VB6, MFC, Delphi, ...).

    - WinForms also has the disadvantage of requiring a large runtime to be installed on the client.

    - Given the above the case for migrating apps to .NET is not (yet) compelling.



    Contrast this with ASP.NET. ASP.NET is a huge leap forward when compared with ASP. Nobody who's developed ASP.NET apps would consider using ASP if they could possibly avoid it.

  • Doesn't ASP.Net also have 'the disadvantage of requiring a large runtime to be installed on the' server?



    I'm glad you consider that 'ASP.NET is a huge leap forward when compared with ASP'. I currently am developing C#.Net and a legacy VB (Studio 97). I don't agree that 'WinForms only provides incremental benefit over the existing mature tools for developing Win32 apps', HOWEVER while they do provide only incremental functionality over previous, I think the new code base and class structure is a huge leap forward.



    The cost here is that it has to be re-learned.

  • I had "the problem" the other way around :-)



    With experience from Win32/COM programing and then having used WinForms for a while, it's a great pain for me to use ASP.NET. Even for a webproject which should be simple. There is so much information/properties missing in for example the Listbox control.



    I love to use WinForms since it gives you the power to do whatever you want(almost.. but the limits really comes from .NET and not WinForms. Try to interop with a library expecting a Cdecl function-pointer from C# ;)). For example I really miss all the properties on listboxes in ASP.NET.



    As earlier commented, when you understand the Win32 API then WinForms makes a lot of sense. If they morphed it into "a bastard child of ASP.NET" then I would either 1) use it and interop heavily with Win32 2) don't use it and wait for a better attempt.

  • Thanks for the opposing viewpoint :). Helped keep things in perspective.

  • And until I found this post, I just thought I was too lame for words. Getting the list of selected values in a listbox was very simple in VB6 - I figured it should only take me a few minutes to solve the problem in VB.net. Well, still no solution.



    Given the general ease of use of the Microsoft developer products, I still think I must be missing something obvious.



    But my misery does appreciate the company :)

  • RE>>Post 3/16/2004 10:53 AM Dennis



    "2) There should be a way for events like combobox.SelectedIndexChanged to tell you whether the event was caused by the user or by your code."



    I think you could pull this off with a little checking at BindingCollection level of the form either that or BindingContext but yes you would still have to do some checking yourself.

    It couldn't be as easy as identifying the sender could it ???

Comments have been disabled for this content.