首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用MVP处理FormClosing

如何使用MVP处理FormClosing
EN

Stack Overflow用户
提问于 2009-06-08 17:38:04
回答 3查看 2K关注 0票数 2

如下所示:

我有一个看起来像这样的视图:

代码语言:javascript
复制
public interface IAddressView
{
     void Close();
     bool IsDirty();
     bool DoesUserWantToDiscardChanges();
}

我有一个演示者,看起来像这样:

代码语言:javascript
复制
public class AddressViewPresenter
{
    private IAddressView m_addressView;
    private Address m_address;

    public AddressViewPresenter(IAddressView addressView)
    {
        m_addressView = addressView;
        m_address = new Address();
    }

    public void CancelButtonClicked()
    {
        bool canClose = true;

        if (m_addressView.IsDirty())
        {
            canClose = m_addressView.DoesUserWantToDiscardChanges();
        }

        if (canClose)
        {
            m_addressView.Close();
        }
    }

    public void SaveButtonClicked()
    {
        // saving logic goes here...removed for brevity
        m_addressView.Close();
    }
}

然后我有一个windows窗体,它有一个取消按钮,一个保存按钮和所有用于显示地址的控件。cancel按钮运行:

代码语言:javascript
复制
m_addressPresenter.CancelButtonClicked();

这又会检查视图是否脏,并提示用户放弃任何更改。太棒了,这就是我想要的。

现在我的问题是,如果用户在没有单击Cancel (取消)的情况下关闭表单(即,他们单击了右上角的"X“,甚至点击了ALT+F4),如何实现同样的目的。我尝试过处理FormClosing事件,但我最终复制了一些代码,如果我单击cancel按钮,弹出消息就会出现两次。这就是我所拥有的:

代码语言:javascript
复制
private void AddressForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.IsDirty())
    {
        if (!this.DoesUserWantToDiscardChanges())
        {
            e.Cancel = true;
        }
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-06-08 18:12:46

您遇到的主要问题是视图包含presenter负责的逻辑,因此我将presenter上的CancelButtonClicked方法更改为如下所示:

代码语言:javascript
复制
public bool ViewRequestingClose()
{
    bool canClose = true;
    if (m_addressView.IsDirty())
    {
        canClose = m_addressView.DoesUserWantToDiscardChanges();
    }
    return canClose;
}

返回值指示视图是否应继续关闭。

视图中用于cancel按钮click和form关闭事件的两个事件处理程序随后将查询演示者,以查看它们是否应该继续关闭。

代码语言:javascript
复制
private void AddressForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if(!m_addressPresenter.ViewRequestingClose())
        e.Cancel = true;
}

private void CancelButton_Click(object sender, FormClosingEventArgs e)
{
    if(m_addressPresenter.ViewRequestingClose())
        this.Close();
}
票数 0
EN

Stack Overflow用户

发布于 2012-03-21 00:21:58

我知道这很古老,但一开始我也觉得这是一件令我困惑的事情。这是我处理这件事的方式。希望有人能偶然发现这一点很有用。

在视图的界面中。

代码语言:javascript
复制
public interface IMainScreenView
{
    event BoolHandler CloseView;

    bool IsDirty { get; set; }
    bool WillDiscardChanges();
}

然后在presenter中为CloseView事件订阅close函数。

代码语言:javascript
复制
public MainScreenPresenter(IView _view)
{
    _view.CloseView += Close;
}

private bool Close()
{
    bool close = true;

    if (_view.IsDirty)
        close = _view.WillDiscardChanges();

    return close;
}     

所以现在,在视图本身中,您可以像往常一样使用FormClosing事件并利用CloseView事件。

代码语言:javascript
复制
public MainForm()
{
    InitializeComponent();

    _presenter = new MainScreenPresenter(this);
    FormClosing += UxMainScreenFormClosing;
}

public bool WillDiscardChanges()
{
    return MessageBox.Show("Changes have been made without being saved. Would you like to continue?", "Exiting", MessageBoxButtons.YesNo) == DialogResult.Yes;
}

protected void UxMainScreenFormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = !CloseView();
}

除了完整性之外,没有其他原因,我还包括了放弃更改检查。这将保持视图的整洁,并将逻辑隐藏在展示器中。我希望它能帮上忙。:)

票数 3
EN

Stack Overflow用户

发布于 2018-09-26 02:34:24

如果有人遇到这种情况,想要一个简单的解决方案。

如果演示者创建视图的一个实例,然后将其打开,请将以下代码放入演示者的构造函数中:

代码语言:javascript
复制
form1.FormClosed += OnFormClose; //form1 is the name of the form that the presenter opens

和下面的处理程序:

代码语言:javascript
复制
private void OnFormClose(object sender, EventArgs e)
        {
            Application.Exit();
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/966035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档