I'm learning the MVP pattern in C# to create simply Windows Forms app. I try recreate and testing this code in different situation and I found the problem with open double form when using method ShowDialog (when I using method Show everything works fine). Maybe someone can help me explain how to resolve this problem or tell me whats I did wrong (maybe I don't understand something or maybe this code is wrong).
App where simple and has 3 form
- Main - with one button to open 2nd form and isMdiContainer is true
public partial class MainView : Form, IMainView
{
public MainView()
{
InitializeComponent();
btnNewForm.Click += delegate { ShowNextView?.Invoke(this, EventArgs.Empty); };
}
public event EventHandler ShowNextView;
}
- Second form - open in MdiContainer with button to open 3rd form
public partial class MyNewFormView : Form, IMyNewForm
{
//Costructor
public MyNewFormView()
{
InitializeComponent();
btnOpenShowDialog.Click += delegate { OpenEvent?.Invoke(this, EventArgs.Empty); };
}
public event EventHandler OpenEvent;
//Static
private static MyNewFormView instance;
public static MyNewFormView GetInstance(Form parentContainer)
{
if (instance == null || instance.IsDisposed)
{
instance = new MyNewFormView();
instance.MdiParent = parentContainer;
instance.FormBorderStyle = FormBorderStyle.None;
instance.Dock = DockStyle.Fill;
instance.BringToFront();
}
else
{
if (instance.WindowState == FormWindowState.Minimized)
instance.WindowState = FormWindowState.Normal;
instance.BringToFront();
}
return instance;
}
}
- Last form - with two buttons OK and Cancel
public partial class AddonView : Form, IAddonView
{
public AddonView()
{
InitializeComponent();
btnOk.Click += delegate { Ok?.Invoke(this, EventArgs.Empty); };
btnCancel.Click += delegate { Cancel?.Invoke(this, EventArgs.Empty); };
}
public event EventHandler Ok;
public event EventHandler Cancel;
private static AddonView instance;
public static AddonView GetInstance(Form parentContainer)
{
if (instance == null || instance.IsDisposed)
{
instance = new AddonView();
instance.FormBorderStyle = FormBorderStyle.None;
instance.Dock = DockStyle.Fill;
instance.BringToFront();
}
else
{
if (instance.WindowState == FormWindowState.Minimized)
instance.WindowState = FormWindowState.Normal;
instance.BringToFront();
}
return instance;
}
}
This 3 forms runs from 3 class presenter
- Main
public class MainPresenter
{
private IMainView mainView;
public MainPresenter(IMainView mainView)
{
this.mainView = mainView;
this.mainView.ShowNextView += ShowNextView;
this.mainView.Show();
}
private void ShowNextView(object sender, EventArgs e)
{
IMyNewForm view = MyNewFormView.GetInstance((MainView)this.mainView);
new MyNewFormPresenter(view);
}
}
- Second
public class MyNewFormPresenter
{
IMyNewForm view;
public MyNewFormPresenter(IMyNewForm view)
{
this.view = view;
this.view.OpenEvent += OpenEvent;
this.view.Show();
}
private void OpenEvent(object sender, EventArgs e)
{
IAddonView view = AddonView.GetInstance((MyNewFormView)this.view);
new AddonPresenter(view);
}
}
- The last one
class AddonPresenter
{
private IAddonView addonView;
public AddonPresenter(IAddonView addonView)
{
this.addonView= addonView;
this.addonView.Ok += Ok;
this.addonView.Cancel += Cancel;
this.addonView.ShowDialog();
}
private void Ok(object sender, EventArgs e)
{
this.addonView.Dispose();
}
private void Cancel(object sender, EventArgs e)
{
this.addonView.Dispose();
}
}
I have 3 interfaces but they have only events, Show, and ShowDialog methods.
So whats the problem ... When I run app open first form, then call second, then call third everything work fine. On last I can close form with OK or Cancel button, and then from second I can call last form and form open single.
But when I run first form, then call second and then calls one more time second (from first) then when I open the last one I have two form. When run one more time button on first form to open second on the last one form will be one 3 times.
When I try call methods SHOW everythings works fine - each form open only one times (but then user can call 3rd form many times) when I use ShowDialog 3rd form open one time (until user don't run on on main menu 2nd form). I read difference between Show and ShowDialog but I have to small experience to find solution to avoid this problem. Could anybody help me resolve this problem?