October 2003 - Posts
Had this query from a member of our UserGroup today:
Query from a member re porting a VB6 app to .Net.
"We have been using MSflex grids with our VB6 work to date.
In .NET, Bill in his wisdom has changed to data bound grids.
To make our software compatible is there a grid in .NET that works the same as the MSflex grid as I have been informed that databound grids will not suit our application.
After expounding my newfound WebForms DataGrid knowledge, I remembered the ComponentOne gear that was included in The Visual Basic .NET Resource Kit, and decided to finally got around to installing my goodies... after the install this is what I found in my Start Menu :):
I'm planning to build some WinForms demo apps to test out the suite - but the offer seems incredibly generous. The WebForms components look fairly impressive too and include the following: WebChart, WebGrid, WebMenu's and WebReports. It's a good time to remember that component vendors serve a very important role in the development process by producing high-quality, fixed price widgets that can be re-used in apps. After installing the ComponentOne suite I remember that I sat behind the ComponentOne guys at the ASP.NET Preview a while back... if you thought that server control authoring was good in V1 - you just wait ;-)
Many major events are marked by a single, significant milestone, remark or activity. Major moments such as these linger in our minds and allow us bookmark points in our past so that we can relive them in the future. Often, a trip to a bookmarked moment will stir feelings and emotions from that time.
With all of the hoopla surrounding the current PDC it will be interesting to see what it is that we remember it by... my guess is that it will be remembered for Blog'ging above all else. The amount, quality and currency of blog entries has been amazing; surely this will stand as a defining moment for blogging beacuse of the new way that people could connect ideas, re-form opinions to have a live impact on a major event.
People that know me well know that - essentially - I'm a web guy. Gimme notepad, and a browser and I'm away. Anyways, in the past year or so I've stepped into more and more WinForms development (for many reasons) and, despite my elevation from WinForms wannabe to WinForms wiz I've continually been scared off by the DataGrid control... NOT ANY MORE!
A couple of days ago I IM'd RoyO about a problem I was having with the DataGrid and he directed me to this little gem:
Winforms Data Binding Lessons Learned
After reading that article I can now say - with total honesty - that the DataGrid holds no fears for me any longer. The point that I had been missing all along was that, you can still get to the source of the grid in much the same way that you get a Container.DataItem when binding to a Web DataGrid. So, provided that you can get the co-ordinates of the current cell in the grid, you can easily get the corresponding item in the IList source. Here's a couple of ways to get the current cell:
Private Sub dg_CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dg.CurrentCellChanged
Dim selectedItem As DataGridCell = dg.CurrentCell
If selectedItem.RowNumber > -1 AndAlso selectedItem.ColumnNumber > -1 Then
GetCellInfoByGridPosition(selectedItem.RowNumber, selectedItem.ColumnNumber)
End If
End Sub
Private Sub dg_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dg.MouseDown
If e.Button = MouseButtons.Left Then
Dim info As DataGrid.HitTestInfo = dg.HitTest(e.X, e.Y)
If info.Row > -1 AndAlso info.Column > -1 Then
GetCellInfoByGridPosition(info.Row, info.Column)
End If
End If
End Sub
The GetCellInfoByGridPosition function is a helper method I wrote to abstract the task of getting the data from a set of co-ordinates:
Private Function GetCellInfoByGridPosition(ByVal row As Integer, ByVal col As Integer) As TableCellInfo
Dim cm As CurrencyManager = CType(BindingContext(dg.DataSource, dg.DataMember), CurrencyManager)
Dim cell As Object = CType(cm.List, DataView).Table.Rows(row).Item(col)
If TypeOf cell Is TableCellInfo Then
Return DirectCast(cell, TableCellInfo)
Else
Return Nothing
End If
End Function
My GetCellInfoByGridPosition function checks to see whether or not the underlying cell is of Type TableCellInfo which is a custom Type of mine. Basically, I created the TableCellInfo class to allow me to bind additional data to the DataGrid cell. What that means is that, after my call to GetCellInfoByGridPosition, I have an instance of a TableCellInfo object to inspect and get data which was only avaiable at the time of binding. In my case it looked something like this:
Dim cellInfo As TableCellInfo = GetCellInfoByGridPosition(row, col)
ActualHours.Text = cellInfo.ActualHours
Comment.Text = cellInfo.Comment
Even though, in the constructor for my WinForms app I do this...
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-AU")
I'm finding that the MIN, MAX functions for DataTable querying seem to use en-US under-the-covers...
mdtmMinDate = Convert.ToDateTime(mobjTimeSheetGrid.Compute("MIN(TimesheetDate)", ""))
mdtmMaxDate = Convert.ToDateTime(mobjTimeSheetGrid.Compute("MAX(TimesheetDate)", ""))
So, I had to roll my own :(
mdtmMinDate = Convert.ToDateTime(mobjTimeSheetGrid.Compute("MIN(TimesheetDate)", ""))
mdtmMaxDate = Convert.ToDateTime(mobjTimeSheetGrid.Compute("MAX(TimesheetDate)", ""))
For Each row As TimeSheet.TimeSheetRow In vobjTimesheetGrid.Rows
Dim tmpDate As String = row.TimesheetDate
If CDate(tmpDate).CompareTo(mdtmMinDate) = -1 Then
mdtmMinDate = CDate(tmpDate)
End If
If CDate(tmpDate).CompareTo(mdtmMaxDate) = 1 Then
mdtmMaxDate = CDate(tmpDate)
End If
Next
Further information about Compute method:
DataTable.Compute - the filter parameter Compute - MS docs
Kirk Allen Evans has provided an excellent dump of features from Scott Guthrie's ASP.NET Whidbey session:
http://weblogs.asp.net/kaevans/posts/33914.aspx
I know that it's an impressive list but, one of my personal favourites is this:
VS.NET no longer mangles HTML
When I first got my alpha bits... I remember spending hours and hours trying to trick the IDE into altering an attribute or tag - but NO... it doesn't.
On top of that feature list, the first articles are already being posted, in this blog entry:
http://weblogs.asp.net/pwilson/posts/33936.aspx
Paul Wilson talks about a Generics article by Rob Chartier and shows some snippets comparing the VB and C# syntax for Generics. He also announces his own article on MasterPages (probably my most favoured feature)
Lastly, Rob is keeping a list of Whidbey stuff here: http://www.mscorlib.com/DesktopDefault.aspx?tabid=263
Even accounting for the hype that can be generated by a football stadium full of Developers that have been overfed Mountain Dew, this is pretty impressive stuff. If you overlay those features with what was mentioned in Bill Gates' keynote, you can't help but feel that MS must have the jump over other providers when it comes to building and deploying the next generation of apps. This stuff is going to be very well received!
Following on from my original posting about using the Compute method of the DataTable to execute aggregate queries, I should add that, the 2nd argument is mandatory as per the docco here:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDataDataTableClassComputeTopic.asp
The filter parameter is the equivalent to a WHERE clause that you can use to limit the number of records that are returned to the aggregate expression. The example I gave in my previous posting was a good example of this where I used a LIKE expression in the filter parameter to get a count of persons whose name met a given criteria:
int countOfName = (int) dt.Compute("Count(Name)", "Name Like '" + entryTextBox.Text + "*'") ;
If the filter is not required, you must pass an empty string as the argument:
eldestYear.Text = dt.Compute( "MAX(DateOfBirth)", "" ).ToString() ;
youngestYear.Text = dt.Compute( "MIN(DateOfBirth)", "" ).ToString() ;
I seem to be making good money out of Scott Mitchell these days ;-)
First he gave me a nice way to generate Rss feeds:
http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/aspnet-createrssw-aspnet.asp
Now, he's released some more source that enables me to easily consume Rss feeds. The RssFeed control is an ASP.NET server control that displays a list of items in any given RSS feed. Basically you just point it at a feed Url and it returns a list of recent items. You can view a live demo of this control here:
http://aspnet.4guysfromrolla.com/blogs/aspnet.aspx
You can also read more about it here:
http://scottonwriting.net/sowblog/posts/374.aspx
This control is a good, real world example of the Data-Bound Templated control from Chapter 20 in the “Developing ASP.NET Server Controls and Components“ book.
Now, I'm off to check out another control of his:
http://workspaces.gotdotnet.com/skmMenu
...apparently it has had some nice features added since its debut.
What a nice guy :-)
A work of art is the unique result of a unique temperament. Its beauty comes from the fact that the author is what he is. It has nothing to do with the fact that other people want what they want. Indeed, the moment that an artist takes notice of what other people want, and tries to supply the demand, he ceases to be an artist, and becomes a dull or an amusing craftsman, an honest or dishonest tradesman. He has no further claim to be considered as an artist. - Oscar Wilde
While there will increasingly be a place for "integrators" of software, I think that there's a point that's lost on all but a few: someone still has to write the apps in the first place.
In my view of the software world, there's 3 broad categories of people: 1) Software creators, 2) Software consumers and 3) Software users.
Sofware creators are people that create applications from the ground up or from low levels of abstractions - this group can be thought of as the primary producers of software.
Software consumers are the integrators. They will take applications that are written by the first group and install, configure and customize these applications. This could be something such as delivering a solution such as: Content Management Server + Sharepoint + Office. Microsoft seem to be spending a lot of energy in targetting this area of sofware.
Software users are the end users of the software products that are created and delivered by the above groups.
Software Creator
- Creates Content Management Server
- Creates Sharepoint
- Creates Office
Sofware Consumer
- Creates a product called "Custom Intranet" which is a bundle of the above products with some custom notification modules and specifically configured for a specific end user
Software End User
- User of the "Custom Intranet" product
Link of the day: http://www.bml.psy.ruhr-uni-bochum.de/Demos/BMLwalker.html
Scott Guthrie has blog'ged about some more tasty titbits that will appear in ASP.NET V2:
Cross Page Postbacks
ValidationGroups: no validation with a Cancel
Workflows with the asp:Wizard control
new ImageGeneration service
Url Rewriting
SiteCounter service
A content management system with the FileSystemProvider
"No Compile" Pages
Forms Authentication with the new Membership and Role Management system
Client-script goodies
Build-Providers
RSS Blog Reader
Read the details here:
http://weblogs.asp.net/scottgu/posts/32965.aspx
As of next week the NDA gets lifted surrounding the ASP.NET Whidbey alpha so, expect to see dozens of articles on Msdn, 4GuysFromRolla, ASPToday and ASPAlliance covering the new stuff. Kent has already bragged mentioned that he's got some gold in his bags!
I cannot stress enough that ASP.NET V2 is not just cool stuff; this version is all real stuff - stuff that you can speak to your PM or boss about - such as productivity, time to market, quality and cost. It may not improve your love life, but it will increase your buffer times :-)
More Posts
Next page »