I'm writing a simple input form using Model-View-Presenter, and I've encountered difficulty with handling the FormClosing event.
When dealing with a normal Form, it has an event that fires on closing called FormClosing
that I can use to cancel the close if I deem it necessary. In this case, I'd like to cancel the form close if the input is bad. For instance:
public interface IView
{
event EventHandler<CancelEventArgs> Closing;
string Input { get; set; }
string ErrorMessage { set; }
}
public class Presenter
{
private IView view;
public Presenter(IView view)
{
this.view = view;
// bind to events
view.Closing += view_Closing;
}
private void view_Closing(object sender, CancelEventArgs e)
{
e.Cancel = !ValidateInput();
}
private bool ValidateInput()
{
bool validationSuccessful = true;
// perform validation on input, set false if validation fails
return validationSuccessful;
}
}
I created my own event handler ( Closing
) because my understanding of MVP states that utilizing anything in System.Windows.Forms
is not a good idea (eg if someday I update my view to WPF). Thus, in the WinForms implementation, I pass the event forward, as such:
public partial class View : IView
{
public event EventHandler<CancelEventArgs> Closing;
public string Input { get { return textBoxInput.Text; } set { textBoxInput.Text = value; } }
public string ErrorMessage { set { errorProvider.SetError(textBoxInput, value) ; } }
public View()
{
InitializeComponent();
}
private void View_FormClosing(object sender, FormClosingEventArgs e)
{
if (Closing != null)
Closing(this, new CancelEventArgs(e.Cancel));
}
}
I've found that even though in my Presenter I tell e.Cancel
to set to true when validation fails, it does not cause the form to cancel the close. I'm clearly doing something wrong here, but I'm not sure what the proper solution is.
I figured it out after experimenting with the solution in another StackOverflow question . I needed to create a new CancelEventArgs
in the View
as follows:
private void View_FormClosing(object sender, FormClosingEventArgs e)
{
CancelEventArgs args = new CancelEventArgs();
if (Closing != null)
Closing(this, args);
e.Cancel = args.Cancel;
}
args.Cancel
properly updated after the Closing
event was called, and successfully mapped the resultant boolean to e.Cancel
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.