Data Design Time Changes Beta1 to Beta2

These are some of the feature changes we’ve made within the Data Design Time features.  When I started writing this document I thought about making it a bulleted list, but then I realized this isn’t a Whidbey Feature list, it’s a delta from Beta1 to Beta 2.  Those interested in the delta probably really want to know what went into the decision.  If you’re looking for a Whidbey Feature list, this isn’t it. When we get closer to Whidbey RTM I’m sure we’ll get something like that pulled together.



Q:         What features does your team own?

A:        My team sits in the middle of a couple of stacks of teams.  We own:

·         The Typed DataSet Designer and Typed DataSet code gen

·         The Data Wizards such as the DataAdapter wizard. 

·         The Data Sources Window

·         Most of Server Explorer

·         Much of the Local Data experience. 

While our focus is primarily on data design time for client apps, including Windows Forms, Devices, Visual Studio Tools for Office and SQL Reporting, we do provide the Data Set designer experience for Web Projects as well.  However, the Venus team owns the overall data design time experience when building web forms.


Q:         Are their differences between VB and C# features?

A:        There are some situations where we couldn’t provide 100% parity between the languages.  For instance VB can wire events using the Handles clause.  This simplifies our code gen as we don’t need to modify a constructor or InitializeComponent to enable the event handling.  This has an effect in the Typed DataSet partial classes for handling DataTable events.  Due to the infrastructure of the SingleFileGenerator, we weren’t able to provide the same experience for C#.  However, in C# you can override the OnColumnChanging method which essentially accomplishes the same task.  Another example is C++ doesn’t support Partial classes, so some features are just disabled.  In general, we’ve tried to provide the same features, but the experience may vary depending on the language feature set.


Q:         Will beta 2 reflect the final product, with just some bug fixes?

A:        For the most part, yes.  There are some minor “features” we still need to complete in our RTM milestone.  However their really isn’t any new feature work.  Just some fit and finish work.


Q:         Where do these feature requests come from?

A:        You, our customers.  Some of the changes are just a continuation of the work we started at the beginning of the product cycle.  Many are based on feedback from usability studies, newsgroups, LadyBug, feedback from attendees at conferences, etc. 


Q:         Can I ask for more?

A:        You can always ask, J.  However, the biggest request we hear is “ship already”.  We’re really trying hard to stabilize the product which means fix bugs, don’t add features.


Q:         What goes into your consideration to make a change?

A:        How many customers would the change affect?  Does it make something easier, or enable a new scenario?  If we changed/added it later would it break compatibility with something we would ship today?  What’s the cost/benefit of making the change? 


Q:         Are these all the changes you’ve made? 

A:        No.  These are a list of the things I think are most interesting.  I didn’t list the bugs we’ve fixed, just the feature work.  Just as a reference, as of January 7th 2005 our Data team alone has resolved over 2,100 bugs just for Beta 2.  The entire VB Product Unit has resolved over 10,500 bugs, and the VS Whidbey team has resolved almost 118,000 bugs just in Beta 2.  I also need to give a lot of credit to our partner teams such as the Client team, VDT, Venus, Devices, VSCore and DataWorks.  Working at Microsoft is a team approach.  There are a lot of people to be leveraged here.


Form Generation

Smart Captions

One of the suggestions from an MVP summit was to put spaces in the labels.  You ask for it, you’ve got it.  I like to say we reward developers for good programming practices.  If you follow “good” naming conventions, such as “FirstName” or even “First_Name”, we’ll create a label of “First Name:”  To accomplish this we use a Regex Expression.  We didn’t have time to expose this as a Tools-Options, but here’s the expression for reference.

Regex.Replace(name, “(p{Ll})(p{Lu})|_+”, “$1 $2″) + “:”


Minimize the noise in Me./this.

In almost all cases the labels of your controls are just labels, and never need access through code.  Yet when you type Me. or This. you see all these labels as well as your data bound controls.  One of the new features the client team added was a property called GenerateMember.  When set to False, the control is not generated as a class scoped member variable.  The control is created within InitializeComponent, added to the Forms collection, then falls out of scope as a variable name.  Since it’s still within the forms collection, the control still exists.  In the rare cases where you do need to interact with the Label the Data Sources Window created, simple select the label, and then toggle the GenerateMember property to True in the property grid.


Smart Defaults

We’ve done a lot of work to start with Smart Defaults.  We may not always generate the same names, or done the same work you might have done, but the way we look at it, it’s gotta be better then TextBox1.  You’ll see this in the Control Names, Labels, and even the code gen we do. 


The DataConnector has been renamed to BindingSource.  In usability studies we watched developers really struggle with the name.  They were absolutely convinced the DataConnector was a Database Connection object.  It didn’t help that that all the other Data Components their used to seeing on the ToolBox were missing, so they just assumed this must be their old connection object.  See my Blog for the thought process behind removing the raw data components from the toolbox.  To avoid this confusion we’ve named it more appropriately to BindingSource.  We’ve also renamed DataNavigator to BindingNavigator.  For the most part, these are the same controls as Beta1 with a rename and a lot of bug fixes.


One of the frequent requests, and one of my own pet peeves was configuring lookup controls such as a ComboBox.  This was a feature that got cut in B1 due to the schedule, but we were able to squeeze most of it back in.  There are two features that were added.  First, was a Smart Tag on Lookups like the ComboBox.  Within the Smart Tag you can set all the normal properties on a combob box.  The tasks even have a ToolTip that describes their purpose.


The second was Connect the Dots.  If you drag a “List” from the Data Sources Window onto a ComboBox VS will set the DataSource, DisplayMember and ValueMember to the elements of the list.  VS will create a BindingSource for the list and set it as the DataSource.  For DataSets, VS will take the first column in the Primary Key and set it as the ValueMember.  If you don’t have a primary key, or the list is a list of objects, VS will just take the first property it finds in the list.  VS will then look for the first string value in the column/list of objects and set it as the DisplayMember.  Remember, I said we use Smart Defaults.  These may not be the right values for you, but they at least get you started.

Save Code Gen

In Beta 1 we took the easy out.  We provided a Save button on the DataNavigator, but we disabled it, and left it to you to figure out the proper code.  We did this because we can really only generate the proper save for a single table.  We haven’t been able to finish the work to provide a “one liner” to save a master/details relationship.  After watching everyone struggle to figure out what the “right” code is, and then most of them forget to call EndEdit, we realized we needed to provide some starter code. 

In Beta 2 we now provide you the basic code gen.  “Smart Defaults” to get you started.

If Me.Validate() Then




    MessageBox.Show(Me, “Validation errors occurred.”, _

        “Save”, _

        System.Windows.Forms.MessageBoxButtons.OK, _


End If

If you’re saving multiple tables, or a master details relationship, you’ll need to add the additional save logic to parse the inserted rows from top->down and deleted rows from bottoms->up.  But it’s a starting point.

Databinding support for DBNull/Nullable(Of T)

To put it nicely, VS2003 data binding wouldn’t handle receiving DBNull very gracefully. While we weren’t able to update all the controls to support Null, at least the data binding infrastructure will support it.  This opens the doors for you and component vendors to support DBNull or Nullable(Of T) on controls such as a DateTime control.  Data binding also supports a NullMapping property.  So, when you do get a null value you can display a replacement value.  On the return trip it will be set back to Null, so be careful what value you choose.  If the default value is a valid value, then it will be converted to Null when pushed to the underlying data bound item.

Configure Master Details

As our feature set has evolved to include Object binding, it became obvious that it was confusing that you could create relationships with objects via the Data Sources Window, but had to use the Configure Master Details smart tag for DataSets.  Yet, the Configure Master Details smart tag didn’t work for objects.  I also believe that wizards are helpful, but they shouldn’t be a crutch and should be used in moderation.  The Data Sources Window will now display relationships under each table. We can now provide a consistent experience for DataSets as well as Objects.  Rather then having to drag the parent on the form then step through a smart tag you can just drag both the Parent and Child objects from the Data Sources Window.  If you drag from the root, you’ll get unrelated DataTable references.  If you drag a table from below another, you’ll get the relationship.  We’ve also cleaned up what we show as the relationship. Rather then showing the usually goofy relationship name FK_Orders_Customers, we will display the related table name.  If the parent has two relations to the same child table we’ll show the relationship name in parenthesis.  With this enhancement, the Configure Master Details smart tag and menu item were no longer needed and have been removed. 

Typed DataSet

Typed DataSet Code Gen goes on a diet.

Typed Column Events

I should start by saying our team loves type safety.  I still live by the motto that code in quotes is a bad thing and should be avoided at all costs.  While we’re working on shipping better tools for code coverage, this shouldn’t be a requirement just to catch simple typo mistakes.  Compile time verification is like checking your airlines website before heading to the airport.  No guarantee the plane will be on time even if the website says so, but if the website says it’s late…

As we had more time to work with these typed events we found many scenarios were incomplete yet we were generating a lot of extra code.  To have a full validation class you really need to compare the proposed values, not just the current values and these properties weren’t available on the EventArgs.  We needed more info at the row level as well.  We generated these events regardless of whether you used them or not.  What we wound up with was a ton of extra code that bloated the data set class for occasional, but incomplete value.  And, we didn’t have all the information available in a typed manner anyway.  Because of these issues, we felt it better to trim back, still support the validation scenario through partial classes, but not default code gen a bunch of extra stuff that you didn’t always use.  In Beta 2, when you double click a column in the DataSet designer, you’ll still get an event handler for the untyped column.  In VB, the default code gen will also demonstrate how you can reference columns in a type safe way so you wind up with a similar experience for a lot less cost. 

For C# we aren’t able to provide the exact experience due to way C# handles event wiring.  However, rather then just cut off C#, we enable it by leveraging the OnColumnChanging overload.

Private Sub EmployeesDataTable_ColumnChanging(ByVal sender As System.Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanging