I hope you guys can help me out as I can't find anything useful that helps with the understanding of my problem:
I'm trying to realize a passive MVP approach on my C# WinForms application which has list views and corresponding detail views.
So far I've got the following structure (pseudo code):
ListPresenter(new Repository(), new ListView(), new DetailPresenter(new DetailView());
Implementation:
public class UserDetailPresenter : IPresenter<IUserDetailView>
{
private IDetailView _view;
public UserDetailPresenter(IDetailView detailView)
{
_view = detailView;
}
public void Show(IUser user)
{
InitializeView(user);
_view.Show();
}
}
public class UserListPresenter
{
//private members (_userRepo, _listView, _detailPresenter)
public UserListView(IUserRepository userRepo, IListView listView, IDetailPresenter detailPresenter)
{
//wire up private members..
_listView.EditCommandFired += this.ShowEditForm;
}
private void OnListViewEditCommandFired(object sender, EventArgs args)
{
_detailPresenter.LoadUser(_listView.SelectedUser);
_detailPresenter.Show(); //modal
}
}
public class UserListForm : Form, IUserListView
{
public event EventHandler EditCommandFired;
public IUser SelectedUser { get { return gridView.FocusedRowHandle as IUser; } }
public void LoadUsers(List<IUser> users)
{
gridView.DataSource = users;
}
// other UI stuff
}
My problem is: I can only show the edit form once. As soon as I try to open it for a second time my View (the form) is disposed (System.ObjectDisposedException).
How do I fix that? Do I have the wrong approach here? Do I either cancel the form's close and just hide it and trust the garbage collector to collect it once the DetailPresenter
is disposed? Do I create (new() up) a new presenter each time the Edit
event is fired? I would then have to introduce some kind of factory as I somehow lose dependency injection. I'd appreaciate if someone could point out how the best practice in this case would look like and what I may be doing wrong here..
I was doing Winforms MVP a while ago so not sure if I can help, but the case my be as follows. In my approach, the view was owning presenter, pseudo code:
In this case instance is still there after closing.
In your case since presenter owns the view, its possible that once presenter is not used, GC disposes presenter and contained view. Or even if presenter is still in use, since view is private GC may collect it once closed.
Try to debug in Release mode and see what happens with closed form instance.
EDIT:
Other idea is: Create instance of view first and then pass to presenter
So approach that may fail (I don' see full code so guessing)
Try
Somewhere in code