2009-06-08 64 views
1

這裏處理的FormClosing雲:如何使用MVP

我有一個看起來像這樣的觀點:

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

回答

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

這樣做更有意義。但是,我仍然遇到問題,當您單擊取消按鈕時,詢問您是否要放棄兩次更改。 – smoak 2009-06-08 18:56:14

2

我知道這是舊的,但我覺得這對我來說也是一個令人困惑的事情。這是我處理這件事的方式。希望有人磕磕絆絆,認爲這很有用。

在視圖界面中。

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

所以現在,在視圖本身,你可以SUBCRIBE到的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(); 
} 

除了完整性之外,沒有任何理由,我還包括丟棄更改檢查。這樣可以保持視圖清潔,並將演示文稿隱藏起來。我希望它有幫助。 :)