I'm a total amateur writing a small App to track to changes in folders. I imagine I'll be keeping information about the directories to watch in one datatable bound to a gridview, when the user clicks a button, the program will create FileSystemWatchers to keep an eye on the directories and they will send their event messages to another datatable bound to another gridview. Where in the wide wide world of OOP should I be declaring, initiating, and manipulating the Datatables? The main form, inside main, in a class, or should I "give up" and use Visual Studio to automagically create a DataSet and stick two tables in it?
Well horses for courses. For a little utility app you would probably be better off using the VS "Visual/RAD" style of programming. Eg drag and drop tables etc on to the form, like most of the tutorials show.
Strictly speaking, and for a larger app, a more correct way would be to make a separate assembly(.dll) that handles data access and you call the classes within that assembly from the main form. This concept goes under a number of terms, but effectively you want to separate your concerns. In other words, let the UI handle UI interactions, have a separate assembly/project/whatever that handles database interactivity, and another separate assembly/project/whatever that handles business logic etc.
That last couple of sentences can mean different things to different people, and there is no 100% correct way to do things.
Some articles that may help:
I agree with KiwiBastard: you get quite a bit of benefit from using the VS tools to generate a typed DataSet.
That just generates classes, though. You still have to manage an instance of the DataSet. For a very simple app, where I haven't factored UI and business logic into different classes, I'd do that in the Form. For an app of any complexity, it's part of the business logic class.
Something that will probably save you a lot of trouble: data binding is good, ADO is good, but certain kinds of ADO code (in particular event handlers on the DataTable) do not play well with data binding. If you're using BindingSources (and, really, you should be), it's generally a good idea to suspend binding whenever you're manipulating the DataSet's objects programmatically (like, when you're adding and deleting rows). The cost of suspending and resuming binding is very small, and it eliminates an entire class of problems that are extremely hard to diagnose.