In my opinion, you should generally try and catch exceptions that you would expect to come out of the code you call in the try block, and let the rest get caught elsewhere. For instance:
try
{
// ... some code that you know may throw ArgumentException or any other known exceptions
}
catch (ArgumentException ex)
{
// ... handle the exception with a good idea of why it was thrown
}
In the catch block, you now can handle the error in a clean, specific way knowing that an invalid argument was passed somewhere in the try block. For example, you could alert the user that they have supplied an invalid argument.
If something happened that you didn't expect (e.g. a NullReferenceException) you probably don't know how to recover from it, so by not catching it you delegate responsibility to the consumer of your component to handle exceptional situations in general.
In short, you should catch exceptions when you know how to handle or correct the error, and allow unknown errors to be caught higher-up the call chain
Make sense?