The current selected answer does NOT handle lines with no spaces such as “jjjjjjjjjjjjjjjjjjjj”x1000 (think about what would happen if someone pasted a URL)
This code solves that problem:
private void txtBody_TextChanged(object sender, EventArgs e)
{
// amount of padding to add
const int padding = 3;
// get number of lines (first line is 0, so add 1)
int numLines = this.txtBody.GetLineFromCharIndex(this.txtBody.TextLength) + 1;
// get border thickness
int border = this.txtBody.Height - this.txtBody.ClientSize.Height;
// set height (height of one line * number of lines + spacing)
this.txtBody.Height = this.txtBody.Font.Height * numLines + padding + border;
}