I recommend not to use pop-up windows but to use some modal windows for a page, like jqModal. IMO it's better for usability than native pop-ups.
About your widgets, what about to look at the problem from the side of a models? For a widget you'll have 2 view models - one for displaying and one for editing settings of the widget. It's better to have 2 different controllers for displaying a widget and for editing settings (I cast SRP principle here). So the first controller will return a widget data model and the second - settings data model. And views, you can use as much as you need, it's hard to recommend something here using only words and without custom implementation of the project in mind.
It's hard to try to answer a vague question. May be you should ask some more specific questions? And check this sample of a portal with widgets, it uses ExtJS library that's very easy to learn and use and it's very powerful.
Edit 02/20/10:
I prefer to use the following approach (I'll use a widget with name FooWidget for example). Create 2 controllers with names FooWidgetDataController and FooWidgetSettingsController. Add routes for urls:
/widgets/FooWidget/data for FooWidgetDataController
/widgets/FooWidget/settings for FooWidgetSettingsController
Create FooWidgetDataModel:
public class FooWidgetDataModel {
public int Column1 {get; set;}
public int Column2 {get; set;}
public int Column3 {get; set;}
}
In the FooWidgetDataController fill the FooWidgetDataModel and return it to some view:
public class FooWidgetDataController : Controller {
public ActionResult Index(){
var model = new FooWidgetDataModel{ Column1=5, Column2=1 }; // loading of data for FooWidgetDataModel
return View(model); // using a view with name Index.ascx or Index.aspx
}
}
Create FooWidgetSettingsModel:
public class FooWidgetSettingsModel {
public bool ShowColumn1 {get; set;}
public bool ShowColumn2 {get; set;}
public bool ShowColumn3 {get; set;}
}
And sample code for FooWidgetSettingsController:
// add some permission verification attribute here
public class FooWidgetSettingsController : Controller {
[AcceptGet]
public ActionResult Index(){
var model = new FooWidgetSettingsModel{ ShowColumn1=true, ShowColumn2=false }; // loading of data for FooWidgetSettingsModel
return View(model); // using a view with name Index.ascx or Index.aspx
}
[AcceptPost, ActionName("Index")]
public ActionResult IndexPost(FooWidgetSettingsModel model){ // model will be automatically binded by built it functionality
// validate model
// save settings if valid
// and return whatever you want here
return RedirectToAction("Index"); // for example, redirecting to edit page
}
}
Using this approach you'll need to create a controller per widget. Probably you'll not like it but using some extensions or base classes you will not need to write a lot of code. And code will be easy to read and simple.
For rendering a widget on a page consider using Html.RenderAction (previously it was in mvc futures assembly, I don't track changes at the moment).
Note, keep your controllers as thin as possible and check some best practices for asp.net mvc (link 1 and link 2).