2

开始:

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

public interface IAddressView
{
     void Close();
     bool IsDirty();
     bool DoesUserWantToDiscardChanges();
}

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

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();
    }
}

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

m_addressPresenter.CancelButtonClicked();

它反过来检查视图是否脏并提示用户放弃任何更改。这很棒,这就是我想要的。

现在我的问题是,如果用户关闭表单而不单击“取消”(即他们单击右上角的“X”甚至按 ALT+F4),如何实现相同的效果。我尝试处理 FormClosing 事件,但最终复制了一些代码,如果单击取消按钮,弹出窗口会发生两次。这是我所拥有的:

private void AddressForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.IsDirty())
    {
        if (!this.DoesUserWantToDiscardChanges())
        {
            e.Cancel = true;
        }
    }
}
4

3 回答 3

3

我知道这很旧,但起初我也觉得这对我来说也是一件令人困惑的事情。这就是我处理这个问题的方式。希望有人偶然发现这很有用。

在视图的界面中。

public interface IMainScreenView
{
    event BoolHandler CloseView;

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

然后在您的演示者中,您将关闭函数订阅到 CloseView 事件。

public MainScreenPresenter(IView _view)
{
    _view.CloseView += Close;
}

private bool Close()
{
    bool close = true;

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

    return close;
}     

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

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();
}

除了完整性之外,我也包括了丢弃更改检查。这使视图保持干净,并将逻辑隐藏在演示者中。我希望它有所帮助。:)

于 2012-03-20T16:21:58.250 回答
0

您遇到的主要问题是视图包含演示者负责的逻辑,因此我会将演示者上的 CancelButtonClicked 方法更改为以下内容:

public bool ViewRequestingClose()
{
    bool canClose = true;
    if (m_addressView.IsDirty())
    {
        canClose = m_addressView.DoesUserWantToDiscardChanges();
    }
    return canClose;
}

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

视图中取消按钮单击和表单关闭事件的两个事件处理程序将查询演示者以查看它们是否应该继续关闭,例如

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();
}
于 2009-06-08T18:12:45.507 回答
0

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

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

form1.FormClosed += OnFormClose; //form1 is the name of the form that the presenter opens

下面是一个处理程序:

private void OnFormClose(object sender, EventArgs e)
        {
            Application.Exit();
        }
于 2018-09-25T18:34:23.680 回答