Why does CBC decryption with a wrong IV still give readable results? While developing some code that uses the .NET AesManaged algorithm, I made some mistakes but was surprised at the results.

My encryption was correct.  I was generating a random IV block and writing it to the file (without encrypting the IV).  Then I was encrypting the plaintext and writing it.

The decryption was wrong though... instead of reading the first block from the file an using it as an IV, it was just using a random IV and decrypting everything.  The first block came out gibberish but the 2nd (and subsequent) ones were decrypted properly!  Why would this be?

And even weirder... when I tried to fix it by encrypting the IV in the encryption code (instead of writing the IV unchanged) the decryption result was the same!  (gibberish then correctly decrypted blocks).

Although I eventually fixed my code, how do these results make sense?
This is what ciphertext block chaining is about - each plaintext block is XORed ("chained") with the previous ciphertext block before encrypting (and after decrypting).

The initialization vector then takes the place of the ciphertext block before the first block (since there is none).

So, mistaking the initialization vector as a ciphertext block does nothing wrong for decryption (other than that you'll get an additional garbage block of plaintext).

You did observe (part of) the malleability property of CBC: One can change the start of the ciphertext (including the IV), even prepend/remove blocks, and the result is still a valid ciphertext, and the plaintext block after the changed one will be changed in a predictable way.

This is used for some attacks on protocols using CBC, when they allow a chosen-ciphertext attack - search for the padding oracle attack, for example.
For this reason, you always (not only for CBC) should use authentication together with your encryption, for example in form of a MAC around your ciphertext (including the IV).