2017-06-07 7 views
2

私はGUIと作業コードを分ける方法を知りたいと思います。 以下のような人為的なコード例は、考え方を網羅していると考えられる最小の開始点です。 C#ワークロジックから別のGUI

この例では、コマンドのソースとしてWindowsフォームを使用し、ディスプレイには (コンシューマ)の結果を使用しています。私は、作業コードがコマンドラインインターフェースからコマンドを得ることができるようにしたい。作業コードは、フォームの知識に依存するべきではありません。 Formは作業コードについてほとんど知っていないはずです。私は、いくつかの消費者が作業コード内のプロパティが値を変更するときに「参照」したいと思います。

私は、コミュニケーションのためのイベント、おそらくはインターフェースを使用していると思いますが、私は何かを開いています。

そこには数多くの提案があります。私はデザインパターンの本を読んできました。私は多くを試してきましたが、私が完全に実装できるほど十分に説明されたセットをまだ見つけていません。

私は普遍的な解決策を望んでいません。小規模で個人的なプロジェクトのために、できるだけ簡単に実装し、維持するために、 がほしいです。私は大きな企業のために設計していません。 私が見つけた

ほとんどのソリューションは、何をすべきかをほのめかすが、イベントが宣言された場合のような 詳細をカバーしていない、そしてそれはどちらかできる問題ので、どのようにコードの他 作品は、イベントの存在を見つけ出します イベントまたはイベントに応答します。私はいつもどこかで、何かを一緒につなぐためのグローバル変数になる必要があります。

ここで私の質問に最も近いのは、これが私の質問です。これはC# Windows Forms App: Separate GUI from Business Logicですが、このソリューションはフォームを使用してワーカーのインスタンスを作成し、興味のあるオブザーバに通知するのではなく、直接値を返します。提供されたソリューションは、2つのクラスを密接に結びつけました。インタフェースおよび反射でいくつか本当にクール作業を行いhttps://www.codeproject.com/Articles/14660/WinForms-Model-View-Presenter が、あまりにも保守性や柔軟ないないようでした:

私はどこでも見つけた最も近いソリューション

はこれです。

以下のソースコードのコメント行には、目的の対話 が表示されますが、実装はされていません。

ファイル#1:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     // tell an instance of JustCounts to increment by 10 
    } 

    // Here, allow JustCounts to cause a call to this (or something 
    // similar, perhaps a property) to inform this code that the TotalCount 
    // property has changed. 
    public void ShowNewTotalCount(int NewTotal) 
    { 
     Console.WriteLine("New Total Count = {0}", NewTotal); 
    } 
} 

ファイル#2

class JustCounts 
{ 
    private int m_TotalCount = 100; 
    // Inform other classes when the following property changes value, 
    // preferably including the value in the notification. 
    public int TotalCount { get => m_TotalCount; } 

    // The code in File #1 needs to result in a call to this method 
    // along with the correct argument value. 
    public void AddThisMuch(int increment) 
    { 
     m_TotalCount += increment; 
    } 
} 

答えて

1

私はネット(4.6.2)の現在のバージョンでこれを基づかせています。

INotifyPropertyChangedを実装すると、プロパティの変更をリッスンできるイベントが発生します。ちょうどキープレスを聞くようなビット、私たちは我々が望む特定のプロパティのためにフィルタすることができます。

public class JustCounts : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private int m_totalCount = 100; 

    public int TotalCount 
    { 
     get { return m_totalCount; } 
     set 
     { 
      if (value != m_totalCount) 
      { 
       m_totalCount = value; 
       NotifyPropertyChanged(); 
      } 
     } 
    } 
} 

我々はそれを暴露しているようTotalCountプロパティを操作するためのメソッドを作成する必要はありません。上記のコードで

public class Form1 : Form 
{ 
    // justCounts is a reference to the object wherever it is coming from 
    justCounts.PropertyChanged += new PropertyChangedEventHandler(JustCountsChangedHandler); 


    private void JustCountsChangedHandler(object sender, PropertyChangingEventArgs e) 
    { 
     // process on event firing 
     Debug.WriteLine($"justCounts TotalCount changed value to {justCounts.TotalCount}"); 
    } 

    // Example of where the handler will fire when called 
    private void button1_click(object sender, EventArgs e) 
    { 
     justCounts.TotalCount++; 
    } 
} 

、私たちは、リスナーがサブスクライブできるJustCountsでイベントを作成しました。

INotifyPropertyChangedインターフェイスを使用すると、TotalCountが変更されるたびにイベントが発生します。

フォーム1では、プロパティの変更をリッスンするハンドラを作成し、ハンドラはそれから処理を実行します。

ワンノート。あなたは、私が仕事 コード内のプロパティはとても価値

を変更したときにこれが機能するためには、我々はその作業コードを仮定しなければならない「を参照してください。」いくつかの消費者を持っているしたいと思います

を言いますそれは加入者(サーバーのようなもの)とは独立して動くことができます。それ以外の場合は、さまざまなサブスクライバに異なるインスタンスがあります。

また、インターフェースを使用することもできますが、使用することはできますが、この場合は必須ではありません。

関連する問題