The answer to this question may turn out to be, "Don't use typed DataSets without using the Binding Navigator." I am curious, however, about the behavior I'm seeing.
So, I created a form where every control was dragged from the data sources explorer.
I deleted the Binding Navigator because it is ugly and inappropriate for this particular form.
I added a ListBox and set the DataSource to the BindingSource.
Notice that the ListBox is not bound, it is just filling itself from the BindingSource.
By some magic that I wasn't counting on, moving around in the ListBox is navigating the BindingSource and all other controls are updating accordingly.
I can make changes to the bound controls and explicitly call EndEdit on the BindingSource and then update the DataSource through the Table Adapter. Works great.
When I make changes in the bound controls and click a new option in the ListBox, I want to be able to check for changes and prompt to save or reset if there are any.
Here is the strange part that I haven't been able to figure out.
No matter what event I attach to, DataSet.HasChanges doesn't return true until the second ListBox change. I've searched and tried dozens of suggestions, most of them ridiculous, but a few that seemed promising. No luck.
Edit: It isn't the second click that is significant, it is when you click back on the original (edited) item.