# Monday, February 27, 2006

What to do when BindingNavigator Raises Exception on AddNew

I got a great question from a reader recently. It's essence reads like this:

If I set up drag and drop data binding to a table that has non-nullable columns, and then press the Add New button twice in the BindingNavigator, I get an unhandled exception on the thread. Since all of the code involved in that call chain is in .NET code and assemblies, how can I handle the exception to keep it from blowing up my app?

If you are not already familiar, to get to this point, you have to create a data bound UI using the Data Sources window, or by hooking up the controls manually. What you end up with after dragging a collection from the Data Sources window onto a form is:

  • A DataGridView or Details form of individual controls
  • A BindingSource component that is set as the data source of the grid or the individual controls
  • A BindingNavigator control that is hooked up to the BindingSource component.

If your data source is a typed data set in the same project, you also get a table adapter instance and data set instance as members on the form, and a Form.Load event handler that fills the appropriate table of the data set so that the app functions without any hand written code. If your data source is coming from a different assembly (an Object data source), then it will be up to you to go retrieve an instance of the collection type and set it as the DataSource property on the BindingSource at runtime to complete the data binding chain.

The way the BindingNavigator gets hooked up, it just points to the BindingSource component and uses the API exposed by a BindingSource to navigate forward and back and to add and delete items from the underlying collection. When you press the Add New button on the BindingNavigator, it calls the AddNew method on BindingSource. The BindingSource passes the call to the underlying collection if it implements the IBindingList interface. Calling AddNew usually also implicitly calls EndEdit on the current item if that item type implements the IEditableObject interface, depending on the collection type's implementation of the AddNew method.

So when dealing with a data table as your collection, you are actually bound to its default DataView. The DataView class implements the IBindingList interface, and the DataRowView class (the items in the collection) implement IEditableObject. When a column in the table is set up so that it does not accept null values, the DataRowView implementation of EndEdit will throw and exception when EndEdit is called if the non-nullable columns have not been provided a value.

The call chain that sets all this up for a standard data set based application is that the BindingNavigator calls into the BindingSource and calls AddNew. This calls into the DataView and adds a new row to the table and starts an editing transaction by calling BeginEdit on the row. When you press the AddNew button a second time, EndEdit is called on the first row you added, which, if you haven't filled in the non-nullable columns, will throw an exception. Since the call chain goes from BindingNavigator to BindingSource to DataView to DataRowView, there is no user code in the call chain where you can logically insert an exception handler.

You could handle the situation in a crude form by having an Application.ThreadException handler, which will catch all unhandled exceptions on the thread. However, this doesn't get called until the stack has unraveled all the way back out to the base of the call stack, so it is a little late to be dealing with the exception in a recoverable way.

A better solution is to inherit from the BindingSource component and provide your own implementation to AddNew. The following implementation (thanks to Steve Lasker and Daniel Herling on the product team in Redmond for coming up with this) shows how:

private class MyBindingSource : BindingSource

{

   public MyBindingSource()

      : base()

   {

   }

 

   public override object AddNew()

   {

      object o = null;

      try

      {

          o = base.AddNew();

      }

      catch (System.Exception ex)

      {

          this.OnDataError(

             new BindingManagerDataErrorEventArgs(ex));

      }

      return o;

   }

}

With this in place, you can just handle the DataError event on the BindingSource component to do whatever is appropriate based on the exception.



.NET | Data Binding | Languages and Tools

Monday, February 27, 2006 6:29:04 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


 # Friday, February 24, 2006

Slides and Demos from Connecting Smart Clients with WCF talk last night - Feb CTP lessons learned

I gave a talk on Connecting Smart Clients at the Microsoft Integration and Connected Systems User Group (MICSUG) last night. I discussed and demoed the basics of using Windows Communication Foundation (WCF) to connect applications, using the newly released Feb CTP.

You can get the slides and demos here:  Slides   Demos

In jumping through the hoops yesterday to get my demos running on the Feb CTP, there were a number of changes that I had to get used to compared to previous builds.

The biggest is that if you run svcutil against a service that uses wsHttpBinding to generate a proxy, you get a proxy service contract that uses custom message contracts to wrap the parameters and return values from each operation contract. XXXRequest and XXXResponse classes are defined in the proxy file for each operation, along with an XXXBody class that actually contains the raw parameter/DataContract types.

If you program against the service contract interface like so:

IAccountsManager mgrProxy = new AccountsManagerProxy();

You will have to create the XXXRequest message contract types to wrap all the parameters you pass into the methods, and unwrap any return values from the XXXResponse types. However, they also expose a public method on the proxy class directly that encapsulates these details so that you can deal directly with the underlying parameters and return values.

So instead of calling IAccountsManager.GetAllAccounts for example, you will have an easier time calling AccountsManagerProxy.GetAllAccounts.

This is true for wsHttpBinding because of the message level security involved in the default binding. If you use basicHttpBinding, or turn down the security on the wsHttpBinding, then you will get more straightforward service contract interface definitions on the client side proxy.

The resulting proxy and service contract look like the following:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

[System.ServiceModel.ServiceContractAttribute()]

public interface IAccountsManager

{

// CODEGEN: Generating message contract since message part accountNo requires protection.

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAccountsManager/CreateAccount", ReplyAction="http://tempuri.org/IAccountsManager/CreateAccountResponse")]

CreateAccountResponse CreateAccount(CreateAccountRequest request);

// CODEGEN: Generating message contract since message part GetAllAccountsResult requires protection.

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAccountsManager/GetAllAccounts", ReplyAction="http://tempuri.org/IAccountsManager/GetAllAccountsResponse")]

GetAllAccountsResponse GetAllAccounts(GetAllAccountsRequest request);

// CODEGEN: Generating message contract since message part fromAccountNo requires protection.

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAccountsManager/Transfer", ReplyAction="http://tempuri.org/IAccountsManager/TransferResponse")]

TransferResponse Transfer(TransferRequest request);

}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public interface IAccountsManagerChannel : IAccountsManager, System.ServiceModel.IClientChannel

{

}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public partial class AccountsManagerProxy : System.ServiceModel.ClientBase<IAccountsManager>, IAccountsManager

{

public AccountsManagerProxy()

{

}

public AccountsManagerProxy(string endpointConfigurationName) :

base(endpointConfigurationName)

{

}

public AccountsManagerProxy(string endpointConfigurationName, string remoteAddress) :

base(endpointConfigurationName, remoteAddress)

{

}

public AccountsManagerProxy(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :

base(endpointConfigurationName, remoteAddress)

{

}

public AccountsManagerProxy(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :

base(binding, remoteAddress)

{

}

CreateAccountResponse IAccountsManager.CreateAccount(CreateAccountRequest request)

{

return base.InnerProxy.CreateAccount(request);

}

public void CreateAccount(int accountNo, string name, decimal initialBalance)

{

CreateAccountRequest inValue = new CreateAccountRequest();

inValue.Body = new CreateAccountRequestBody();

inValue.Body.accountNo = accountNo;

inValue.Body.name = name;

inValue.Body.initialBalance = initialBalance;

CreateAccountResponse retVal = ((IAccountsManager)(this)).CreateAccount(inValue);

}

GetAllAccountsResponse IAccountsManager.GetAllAccounts(GetAllAccountsRequest request)

{

return base.InnerProxy.GetAllAccounts(request);

}

public BankingBusinessLayer.Account[] GetAllAccounts()

{

GetAllAccountsRequest inValue = new GetAllAccountsRequest();

inValue.Body = new GetAllAccountsRequestBody();

GetAllAccountsResponse retVal = ((IAccountsManager)(this)).GetAllAccounts(inValue);

return retVal.Body.GetAllAccountsResult;

}

TransferResponse IAccountsManager.Transfer(TransferRequest request)

{

return base.InnerProxy.Transfer(request);

}

public void Transfer(int fromAccountNo, int toAccountNo, decimal amount)

{

TransferRequest inValue = new TransferRequest();

inValue.Body = new TransferRequestBody();

inValue.Body.fromAccountNo = fromAccountNo;

inValue.Body.toAccountNo = toAccountNo;

inValue.Body.amount = amount;

TransferResponse retVal = ((IAccountsManager)(this)).Transfer(inValue);

}

}



.NET | Community | Languages and Tools | Speaking | WinFx

Friday, February 24, 2006 3:04:57 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 

.NET Rocks and DNRtv episodes up

I recorded a DNR and DNRtv last week in New London and they are already up on the site.

You can download/listen to the .NET Rocks! epsidode here: http://www.dotnetrocks.com

And the DNRtv here: http://www.dnrtv.com

In the DNR episode, we talk about data binding, ClickOnce and a few other related topics.

This DNRtv shows how to do some of the data binding stuff in the designer. Keep your eyes out for another episode in a week or so on ClickOnce deployment.



.NET | ClickOnce | Community | Data Binding | Languages and Tools | Speaking

Friday, February 24, 2006 2:45:20 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 

My Brother's Band - Thank-U-Drive Thru - On KLOS Mark and Brian Show Live March 3rd

Some of you who know me know my brother, Glenn Noyes, is a musician in LA and I am very proud of him. Even though he never was part of a band that achieved true "rock star" status, he has had a great career and is well known in the industry. Besides playing in a lot of bands over the years, he has been managing West LA Music, the top music store in the Hollywood area and a favorite for many movie stars and big rock bands, for over a decade.

His band Thank-U-Drive Thru is very popular in the SoCal area, playing mostly in the south bay area of LA. They do mostly cover tunes these days since they mainly play for fun.

On Friday March 3rd, they will be featured on a show that the nationally syndicated Mark and Brian show is doing, described below. Check it out if you have a chance! If you have never heard the Mark and Brian show, they are definitely the funniest morning show I have heard anywhere. I always look forward to listening when I am on travel in the LA area because I invariable laugh my ass off, and KLOS is one of my favorite stations in the area for music preference anyway.

 

If you are unable to see the message below, click here to view.
THANK-U-DRIVE THRU
John
                        McGonigle on Bass & Vocals Glenn Noyes on Drums & Vocals Kevin Layland on Guitars Tim Santo on lead vocals
John McGonigle Glenn Noyes Kevin Layland Tim Santo
       
       

News

THANK U DRIVE THRU
LIVE ON THE RADIO!!

On Friday, March 3rd, THANK U DRIVE THRU will be performing live on KLOS 95.5 Mark and Brian morning show! We were chosen to be the house band for the "2 Strangers and a Wedding" promotion that has been running for the last month and has been the talk of Los Angeles. They have been interviewing potential brides and grooms on the air for the last month and on March 3rd, two complete strangers will walk down the aisle to be married and will see each other for the 1st time as they walk down the aisle! They are receiving about $50,000 in rings, a Hawaiian honeymoon, a BMW, etc... Crazy!

Anyway, we will be playing in the main ballroom on the Queen Mary in Long Beach. The wedding starts at 7:45am. We will be playing the "first dance" at about 8:15am and then we will be playing the rest of the show going in and out of the commercial breaks until 10am. The show goes off the air at 10am, but we will continue to play for a couple of hours for the after party! If you live in a city that gets "The Mark and Brian show", tune in, as it is broadcast in about 13 cities across the country. If not, you can go to
www.955klos.com and scroll down to "listen to Mark and Brian live" and click on that and you can hear the broadcast in real time streaming on your computer! (This only works during the show 6-10am Mon-Fri) If you want any more info, either email Glenn at < /font>gnoyes@thankudrivethru.com or go to www.markandbrian.com or www.955klos.com
Listen in Friday March 3rd and be a part of this crazy event and support
THANK U DRIVE THRU! You can also call Mark and Brain and tell them what a great choice they made for the house band by calling 1-800-955-5567 (between 6-10am) and let them THANK U DRIVE THRU ROCKS!
Rock On!
THANK U DRIVE THRU!!!
 

 

 

 

 



 

 




Friday, February 24, 2006 12:40:30 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


 # Wednesday, February 22, 2006

Connecting Smart Clients with WCF - MICSUG talk tomorrow night

Come on out for the inaugural meeting of the Microsoft Integration and Connected Systems User Group (MICSUG) at the Microsoft Reston offices tomorrow night at 7 pm. I'll be giving a presentation on using WCF to connect smart clients in a distributed environment.

Should be a great time!



.NET | Community | Speaking | WinFx

Wednesday, February 22, 2006 1:56:36 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 

Debugging SQL Express Apps - Beware VS Copy To Output Directory default

Here is a little trick that has bitten me on more than one occasion, and just bit someone who attended my data binding session in NYC the other night.

Here is the setup to be bitten by the defaults in Visual Studio:

- Add a SQL Express database to your project

- Edit the schema, add some tables, etc.

- Write some code / data binding that uses the database

- Run a debug session adding records or modifying ones you created through the designer.

- Save the changes from your running debug session.

- Shut down the app and run another debug session, and your changes are no longer there.

First instinct at this point is "there is something screwed up with my data binding / data access code". That instinct may be wrong (although we are all good at writing bugs as well).

When VS adds the MDF file to your project, it places it and its related LDF file in the project root folder, and add them to your project in solution explorer. The file properties for the MDF file include Build Action = Content, and Copy To Output Directory = Copy Always.

What is happening is that your changes are being persisted to the copy of the MDF file that was placed in your build output directory (bin\debug) on the first debug run. Then on the second debug run, the unchanged MDF file from the project root folder is copied down into the build output folder, overwriting the one that was there with your changes from the previous run. As a result, it looks like your changes were not persisted when in fact they were (or may have been if your code was correct).

The solution is that whenever you add a SQL Express DB to your VS project, you probably want to change the Copy To Output Directory property for the file to Copy If Newer.



.NET | Data Binding | Languages and Tools

Wednesday, February 22, 2006 1:21:46 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


 # Monday, February 20, 2006

IDesign Newsletter

We have decided to start putting out a periodic newsletter at IDesign with information on the content that we are producing in the form of articles, books, blog posts, and public presentations. There will also be information in there for various events that we are involved in, such as conferences and classes.

If you would like to tap into another great informational resource that just shows up now and then, please subscribe to the IDesign newletter.



.NET | Community

Monday, February 20, 2006 7:44:40 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 

.NET Rocks! and .NET Rocks! TV Episodes coming up
I went up to New London this week and taped two episodes of DNRtv and one DNR with Carl and Richard. The DNRtv episodes should go up in the next two weeks, one on data binding and one on ClickOnce deployment. The DNR will air on 22 March. Check them out!

.NET | ClickOnce | Community | Data Binding | Languages and Tools | Speaking

Monday, February 20, 2006 6:10:56 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 

Data Binding with Windows Forms 2.0 Slides/Demos from NYC.NET

I gave a talk on data binding in NYC this Thu night. Had a great time. Lively crowd as always, lots of good questions and interaction.

Here are the slides and demos:

Slides    Demos



.NET | Community | Data Binding | Languages and Tools | Speaking

Monday, February 20, 2006 6:06:58 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


 # Wednesday, February 8, 2006

Selected as Microsoft Regional Director

Wow. What can I say. Wow. I'm not worthy!

I've been selected for the Microsoft Regional Director program (http://msdn.microsoft.com/isv/rd/) to represent the state of Virginia. Very cool opportunity. More chances for early exposure to new technologies coming out of Microsoft and the opportunity to influence what they become, more opportunities to help the community learn and adopt those technologies, and one of the biggest benefits is being able to collaborate with the other 150 or so RDs, which is quite a brain trust (myself excluded).

I thought being an MVP was a great opportunity, but this makes that pale in comparison!



.NET | Community

Wednesday, February 8, 2006 12:27:28 PM (GMT Standard Time, UTC+00:00)
Comments [7]  | 


 # Saturday, February 4, 2006

Blogsphere-driven Dilbert
I've been waiting to see this Dilbert. Scott Adams went out to the blogsphere a couple months ago to get ideas for a credible sounding statement about web services, and this was the result. Pretty funny context!

Blogging

Saturday, February 4, 2006 1:34:15 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 

TDC Class Demos
For the folks from my Master class in CA this week, here are the live demos. Anyone's welcome to grab them, most have project names that indicate what was being demoed.

.NET | Languages and Tools | Speaking

Saturday, February 4, 2006 1:28:28 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


















May, 2013 (2)
April, 2013 (2)
March, 2013 (2)
February, 2013 (2)
January, 2013 (2)
December, 2012 (3)
November, 2012 (1)
October, 2012 (1)
August, 2012 (2)
June, 2012 (2)
May, 2012 (3)
April, 2012 (1)
March, 2012 (2)
February, 2012 (2)
January, 2012 (1)
November, 2011 (4)
October, 2011 (1)
September, 2011 (2)
August, 2011 (1)
July, 2011 (1)
May, 2011 (5)
March, 2011 (4)
February, 2011 (2)
January, 2011 (3)
November, 2010 (4)
October, 2010 (1)
September, 2010 (5)
August, 2010 (5)
July, 2010 (6)
June, 2010 (8)
May, 2010 (2)
April, 2010 (2)
January, 2010 (1)
December, 2009 (3)
November, 2009 (2)
October, 2009 (3)
September, 2009 (3)
August, 2009 (2)
July, 2009 (3)
May, 2009 (3)
April, 2009 (2)
March, 2009 (1)
February, 2009 (2)
January, 2009 (2)
December, 2008 (1)
November, 2008 (2)
October, 2008 (5)
September, 2008 (4)
August, 2008 (2)
July, 2008 (1)
June, 2008 (2)
May, 2008 (2)
April, 2008 (3)
February, 2008 (6)
January, 2008 (3)
December, 2007 (1)
November, 2007 (1)
October, 2007 (5)
September, 2007 (1)
July, 2007 (3)
June, 2007 (8)
April, 2007 (2)
March, 2007 (4)
February, 2007 (1)
December, 2006 (2)
November, 2006 (9)
October, 2006 (5)
September, 2006 (3)
August, 2006 (2)
July, 2006 (4)
June, 2006 (5)
May, 2006 (10)
April, 2006 (4)
March, 2006 (2)
February, 2006 (12)
January, 2006 (7)
December, 2005 (2)
November, 2005 (15)
October, 2005 (6)
September, 2005 (7)
August, 2005 (3)
July, 2005 (10)
June, 2005 (11)
May, 2005 (7)
April, 2005 (8)
March, 2005 (6)
February, 2005 (2)
January, 2005 (6)
December, 2004 (3)
November, 2004 (5)
October, 2004 (2)
September, 2004 (5)
August, 2004 (13)
July, 2004 (6)
June, 2004 (14)
May, 2004 (17)
April, 2004 (12)
March, 2004 (8)
February, 2004 (10)
January, 2004 (14)
December, 2003 (9)
November, 2003 (13)
October, 2003 (3)

Sign In
Copyright © 2006-2012 Brian Noyes. All rights reserved.

designed by NUKEATION STUDIOS