I don't see a problem - user control is nothing but a view. And a presenter can interact with multiple views at a time. So in this case, your presenter can have reference of say 4 views (one for page, two for user controls and last one for sub-user control).
Alternatively, you want to have single view per presenter and in such case, you can see user control as child view of the parent view(page) and so parent view need to bubble up and down view interactions meant for presenter. However, I would prefer the earlier approach where presenter handling interaction multiple views.
See this related question on SO on how wiring is done: https://softwareengineering.stackexchange.com/questions/60774/model-view-presenter-implementation-thoughts
Finally, you may want to look at MVVM pattern which I believe works great for compositional UI. Instead of presenter, you will have view model that will control the interaction between view and model - however, unlike presenter, view model does not know about view - rather view observes (and updates) view model to render itself. See this article here (View Model is referred as Presentation Model): http://www.codeproject.com/Articles/23340/Presentation-Model-in-Action
EDIT:
To be honest, I don't prefer any of your approaches. I like MVP implementation where presenter holds reference to view via interface (no tight coupling) and view does the wiring i.e. creates presenter instance and inject the view references. The presenter listens to view events and call methods on view. View never calls directly on presenter's methods. (Other variations of MVP are possible - see the SO answer that I had sought). With this, I will explain two approaches that I had explained earlier.
Approach 1:
Each user control is an independent view. There will be common presenter that will handle multiple views. For example,
public class Presenter1
{
IView1 _view1;
IView2 _view2;
public Presenter1(IView1 view1, IView2 view2)
{
_view1 = view1;
_view2 = view2;
_view1.OnSave += OnSave;
_view1.OnSomeEvent += OnSomeEvent;
_view2.OnFoo += OnFoo;
}
public void OnSave()
{
var data1 = _view1.GetData();
var data2 = _view2.GetData();
// update model
...
}
public void OnSomeEvent()
{
// inform view2 about it
_view2.DoOnSomeEvent();
}
...
}
public partial class MyPage : Page, IView1
{
public void Page_Load(...)
{
//do wire up
_presenter = new Presenter(this, usercontrol1);
}
...
}
Basic idea is that view does not do cross talk. If user control needs to inform page some thing, it would raise an event that is caught by presenter and it informs page about it. Views are passive and handles UI.
Approach 2:
Usercontrol and Page interacts. In such case, Page will act as a ultimate view and Presenter will hold reference to it. Control's events will be handled by page and page will bubble up the event if necessary. For example,
IView1 : IView2 { }
public class Presenter1
{
IView1 _view1;
public Presenter1(IView1 view1)
{
_view1 = view1;
_view1.OnSave += OnSave;
_view1.OnSomeEvent += OnSomeEvent;
_view1.OnFoo += OnFoo;
}
...
}
public partial class MyPage : Page, IView1
{
public void Page_Load(...)
{
//do wire up
_presenter = new Presenter(this);
// handle user control events
UserControl1.Foo += UserControl1_OnFoo();
UserControl1.XyzEvent += UserControl1_XyzEvent();
}
...
private void UserControl1_OnFoo(...)
{
// bubble up to presenter
OnFoo(..)
}
private void UserControl1_XyzEvent(...)
{
// private interaction (purely about some UI manipulation),
// will not be bubble up to presenter
...
}
}