我發現最好的辦法,以這個被轉移你的應用程序設計成某種形式的模型 - 視圖 - 的*模式,其中爲的WinForms Model-View-Presenter 通常是一個不錯的選擇。
這種方式你有一個主持人/控制器類負責所有的邏輯,你有視圖持有的UI代碼。在Winforms中,您通常可以實現這一點,讓您的表單類實現一個IView接口,該接口定義它可以執行的所有操作。
然後,您提供的形式(通過它在聲明爲接口)演示 - 與構造函數依賴注入是通過它的典型方式
所以,在你的榜樣,你移動你的AccessToCsvFileVerificationInputs
方法插入到演示者類中,並向演示者傳遞實現正確界面的表單實例,並說明該表單可以執行的所有操作。
事情是這樣的:
public class CsvFilePresenter
{
private ICsvFileView view_;
public CsvFilePresenter(ICsvFileView view)
{
view_ = view;
}
public void AccessToCsvFileVerificationInputs(bool access)
{
// Code omitted for brevity
}
}
現在這種方法隨處可見,你引用像控制UI功能直接與你,而不是引用接口:
public void AccessToCsvFileVerificationInputs(bool access)
{
view_.EnableSelectCSVFilePath = access;
view_.EnableNumberOfColumns = access;
view_.EnableCurrencyPair = access;
// And so on...
}
我故意留控制集合了 - 怎麼樣你處理這些將取決於具體情況。
因此,例如,你有這樣的ICsvFileView接口:
public interface ICsvFileView
{
bool EnableSelectCSVFilePath { get; set; }
bool EnableNumberOfColumns { get; set; }
bool EnableCurrencyPair { get; set; }
}
這個ICsvFileView的具體實施可能是這樣的:
public partial class Form3 : Form, ICsvFileView
{
public Form3()
{
InitializeComponent();
}
bool ICsvFileView.EnableSelectCSVFilePath
{
get
{
return btnSelectCsvFilePath.Enabled;
}
set
{
btnSelectCsvFilePath.Enabled = value;
}
}
bool ICsvFileView.EnableNumberOfColumns
{
get
{
return nudNumberOfColumns.Enabled;
}
set
{
nudNumberOfColumns.Enabled = value;
}
}
bool ICsvFileView.EnableCurrencyPair
{
get
{
return cbCurrencyPair.Enabled;
}
set
{
cbCurrencyPair.Enabled = value;
}
}
}
現在你已經做到了這一點,你可以測試您的邏輯行爲(如演示者所表達的)及其與View的交互,方法是傳遞一個模擬的界面實例並設置該模擬的期望值。
請注意,如果這一切似乎有點複雜難懂那是因爲它是! Winforms的設計並非真正考慮到這種情況 - 其他框架(如WPF)也是如此,並且使這一切變得更加容易。如果你可以改變,我建議考慮它。
Martin Fowler的網頁上我掛已經退休這種模式,它移動到兩個不同的模式 - 我會繼續的術語,雖然,因爲它是衆所周知的。他的新Passive View接近我一直看MVP。
嗨大衛,感謝羚牛的時間來回答我的問題。我已經通過你的回答讀了幾次n我想我現在明白了。我要去一試,看看我是怎麼回事。我在此同時將此標記爲答案n + 1。感謝你的寶貴時間! – 2012-08-04 17:52:57
@HansRudel完全沒問題。如果試過後,如果沒有任何意義,只留下評論,我會盡力澄清。還有幾個人們構建Winforms MVP框架的示例項目 - 谷歌Winforms和MVP(或MVC),你應該找到一些。 – 2012-08-04 17:54:46
早上,我仍然有一些問題了解這是如何工作的。我對MainForm部分類如何實現一個接口(IMainView)有基本的瞭解,該接口指定了MainForm需要實現的所有事件(按鈕點擊等)和屬性等。 MainForm實例然後通過DI傳遞給MainPresenter。我不明白,但是我怎樣才能訪問MainPresenter類中的控件屬性?我只聲明IMainForm接口中的方法,所以我如何訪問控件屬性? (對不起,如果這是一個愚蠢的問題)。 – 2012-08-06 08:33:18