Your description of how to create a spectrogram is correct. Here's an explanation with a little more detail:
First, create a WaveChannel32, using a WaveFileReader. This will output a PCM byte stream. Then read 4 times the size of your FFT bytes from the WaveChannel32 into a buffer. Convert every four bits in the buffer into an integer.
It's important at this point to use a window function on our interval, to emphasise amplitudes closer to the current time stamp.
I'd then suggest using the Exocortex FFT library to calculate the FFT. The Fourier.FFT method will convert an array of complex numbers to its corresponding Fourier transform. Then ignore the second half of the array produced, to prevent aliasing.
The first half of the array corresponds to the column of the spectrogram at our current time stamp. Each number in the array corresponds to a single pixel in the spectrogram, the frequency of which is determined by the index of the array (equally spaced throughout 0 to 22050Hz). The darkness of each pixel is determined by the magnitude squared of the complex number corresponding to said pixel.
Here's some sample code for producing one column:
var waveChannel = new NAudio.Wave.WaveChannel32(new NAudio.Wave.WaveFileReader("file path"));
var buffer = new byte[4096*4];
waveChannel.Read(buffer, 0, 4096*4);
var samples = new ComplexF;
for (var i = 0; i < 4096, i++)
samples[i].Re = BitConverter.ToSingle(buffer,i*4);
// Window should be pre-populated with values from your window function
samples[i].Re *= Window[i];