8

ここ数日、winforms を使用して MVP パターンをいじっていますが、どうすればよいかわからないことが 1 つだけあります。別のビューからサブフォームを作成する方法を教えてください。これは有効なオプションでしょうか。

 public class MyForm : IMainFormView
    {
        private MainFormPresenter pres;
        public MyForm() { pres = new MainFormPresenter(this); }

        //Event from interface.
        public event EventHandler<EventArgs> LoadSecondForm;

        public void SomeButtonClick()
        {
            LoadSecondForm(this, EventArgs.Empty);
        }
    }

    public class MainFormPresenter
    {
        private IMainFormView mView;

        public MainFormPresenter(IMainFormView view) {
            this.mView = view;
            this.Initialize();
        }

        private void Initialize() {
            this.mView.LoadSecondForm += new EventHandler<EventArgs>(mView_LoadSecondForm);
        }


        private void mView_LoadSecondForm(object sender, EventArgs e) {
            SecondForm newform = new SecondForm(); //Second form has its own Presenter.
            newform.Load(); // Load the form and raise the events on its presenter.
        }
    }

私は主に、このパターンを使用してサブフォームをロードする方法と、最初のページからサブフォームに ID を渡す方法に関心があります。

ありがとう。

4

3 に答える 3

8

http://www.rickardnilsson.net/post/The-Humble-dialog-v2.aspx

上記のリンクは、私がこれに答えるのに最も近いものです。これを解決しようとするほとんどの試みには、何かが望まれています。

于 2009-06-30T20:23:30.143 に答える
2

この他のSOの質問を見てください。WinFormsではなくWPFに関連していますが、問題は同じようです。

基本的に、補助ウィンドウをサービス(WindowsServiceまたはDialogServiceなどと呼ぶ場合があります)に表示する必要があると思います。それは、物事を見通しに入れるのに役立ちます。なぜなら、それを理解するとすぐに、依存性注入が答えになるからです。

あなたの答えでは、これをイベントでモデル化しますが、DialogServiceのShowDialogメソッドを呼び出すより明示的なモデルを好みます。ただし、各アプローチの仕組みはそれほど違いはありません。

于 2009-07-04T19:36:18.030 に答える
1

これに関するいくつかのコメント

まずこれ

    private void mView_LoadSecondForm(object sender, EventArgs e) {
        SecondForm newform = new SecondForm(); //Second form has its own Presenter.
        newform.Load(); // Load the form and raise the events on its presenter.
    }

SecondForm の代わりに ThirdForm を使用するとどうなりますか? newform = new SecondForm のすべての呼び出しを見つけて、変更を加える必要があります。

代わりに、コマンド オブジェクトで SecondForm の作成をラップする必要があります。

   public class CreateSecondForm : ICommand
    {

        public void Execute() {
            SecondForm newform = new SecondForm(); //Second form has its own Presenter.
            newform.Load(); // Load the form and raise the events on its presenter.
        }

    }

次に、ここと他の場所で2番目のフォームが表示され、この構文が使用されます

private void mView_LoadSecondForm(object sender, EventArgs e) {
    CreateSecondForm createCmd = new CreateSecondForm(); 
    createCmd.Execute(); // Load the form and raise the events on its presenter.
}

SecondForm を完全に新しいフォームに置き換えたい場合、必要な場所は 1 つだけです。ステータスまたはセットアップ値を渡したい場合は、コマンドのコンストラクターを使用します。別の Presenter または View を渡して、コマンドにそのインターフェイスから情報を取得させることもできます。

私がお勧めするもう 1 つのことは、新しいコマンドを使用する代わりに、ビューを実装するフォームを登録することです。これは初期化中に行われ、レジストリはメイン アプリケーション クラスからハングアップします。

例えば。

public class MySecondForm : ISecondFormView, IViewForm
    {
        //Stuff ....
       Public ViewFormEnum ViewFormType {
          return ViewFormEnum.SecondForm;
       }
        //Stuff ....
    }

ソフトウェアの他の場所

public void InitializeApp() {
        //Stuff ....
        MyApp.ViewForm.Add(new MySecondForm);

        //Stuff ....

}

次に、コマンドは次のように設定されます。

   public class CreateSecondForm : ICommand
    {
        myApp theApp;
        public CreateSecondForm(myApp thisApp) {
           theApp = thisApp;
        }

        public void Execute() {
            SecondForm newform = theApp.Find(ViewFormEnum.SecondForm);
            if (newForm != null) 
               newform.Load(); // Load the form and raise the events on its presenter.
        }

    }

C# は私の主要言語ではないことをご容赦ください。この方法の利点は、フォームを含むアセンブリを別のフォーム セットを持つ別のアセンブリに交換できることです。これは、フォームの代わりにモック クラスを作成できるテストの自動化に特に役立ちます。完全なアプリケーションのサブセットをリリースするのに役立つ null ビューを処理するように設定することもできます。

コマンドを使用してビューの作成をラップすることを強くお勧めします。View を登録するという 2 番目の提案は、アプリケーションによってはやり過ぎかもしれません。私の CAD/CAM アプリケーションには、2D 金属切断テーブルの設定と制御のさまざまな側面に使用される多数のダイアログといくつかの異なるメイン フォームがあります。ただし、私の会社の他のアプリケーションの一部では、ほとんどが単純なユーティリティであるため、単純なアプローチを使用しています。

于 2009-07-08T19:11:33.410 に答える