I believe the view should implement an interface and be passed into the controller, usually through the constructor. This way a controller could use the fields of the view interface to get at the values of the controls the view uses. It could also use any model of your choosing. This would give you the loose coupling between the model and view that you want.
The same could be done for the model by passing a repository for your model in through the constructor. The repository methods could then return interfaces that your model classes must implement.
You could then have the controllers implement an interface and get the appropriate controller at run time using an IoC container (which would automatically supply the controller with the appropriate view and model repository. That would make your controllers able to be swapped out easily to replace the current view/model combination for a different one. In general, however, I find this to be unecessary because I only ever have one controller for each type of view (view interface).