I currently use a structure where the whole system is split into logical parts, each part being a separate Visual Studio solution. Each such solution is contained in a folder structure looking like this:
[logical part name]
|-doc
|-lib
|- // any non-GAC-assemblies needed by the projects in the solution
|-src
|-Production
| |-Project1
| |-Project2
|-Tests
|-UnittestProject1
|-UnittestProject2
|-tools
|- // any tools needed for automated builds and such
// (NUnit, NCover, MSBuild tasks, ...)
This does require some moving around of files (output from one logical part that is referenced by another needs to be moved into that other part's lib folder, for instance) but this can easily be automated within an MSBuild script. We also have such an MSBuild script that calls the MSBuild scripts of each of the logical parts in order, and moves the output into the appropriate lib folders. This way I can build the logical part that I am currently working with in one step, and also make a build of the full system with one click (or, well, double click).
We have used that structure in the current project for the last year and a half or so, and it seems to work out rather well.