3

MVPについて学び、WinFormsでそれを使用してテストアプリを作成してみました。フォーム/ビュー間を移動する方法について、よく説明されている例を見つけるのに苦労しています。例として、プログラムが起動し、ログインダイアログを表示して、ログインが成功した場合はメインビューに移動します。現時点では、私のMainメソッドは次のようになっています。

static void Main()
{
   var loginView = Injector.Resolve<ILoginView>();
   if (loginView.DoLogin() != LoginResult.OK) return;
   var mainView = Injector.Resolve<IMainView>();
   Application.Run(mainView); // won't work as mainView isn't a form
}

Injectorオブジェクトは、IoCツール(現在はStructureMap)の単なるラッパーです。重要なのは、コンストラクターインジェクションを介して実際にインスタンスを作成する必要があるため、インジェクターを介してインスタンスを手動で作成するべきではないことを読みました。

私はこれをある程度まで行うことができましたが、ナビゲーションに関してはできませんでした。私は自分の見解を上品に移動する方法を考えることができず、ここの誰かがこれに光を当てるかどうか疑問に思っていましたか?アプリケーションコントローラについて少し読んだことがありますが、それを明確に示す例は見つかりませんでした。

4

3 に答える 3

3

ナビゲーションの質問に関して:

私はこれをある程度まで行うことができましたが、ナビゲーションに関してはできませんでした。私は自分の見解を上品に移動する方法を考えることができず、ここの誰かがこれに光を当てるかどうか疑問に思っていましたか?アプリケーションコントローラについて少し読んだことがありますが、それを明確に示す例は見つかりませんでした。

以下は、私が使用した構成の簡略化されたバージョンです。メソッドが呼び出されると、セットアップフックとティアダウンフックが自動的に呼び出されることに注意してくださいNavigateTo。また、@ AlexBurtsevに+1します。彼の答えは、これとまったく同じアプローチを示唆しています。

// Presenter can and should offer common services for the
// subclasses 
abstract class Presenter
{

   public void Display()
   {
      OnDisplay();
   }

   public void Dismiss()   
   {
      OnDismiss();
   }


   protected virtual OnDisplay() // hook for subclass
   {   
   }

   protected virtual OnDismiss() // hook for subclass
   {   
   }

   private NavigationManager _navMgr;

   internal NavigationMgr NavigationManager
   {   
      get
      {
         return _navMgr;
      }
      set
      {
         _navMgr = value;
      }

   }

}

// NavigationManager is used to transition (or navigate) 
// between views
class NavigationManager
{

   Presenter _current;

   // use this override if your Presenter are non-persistent (transient)
   public void NavigateTo(Type nextPresenterType, object args)
   {   
      Presenter nextPresenter = Activator.CreateInstance(nextPresenterType);   
      NavigateTo(nextPresenter);   
   }

   // use this override if your Presenter are persistent (long-lived)
   public void NavigateTo(Presenter nextPresenter, object args)
   {
      if (_current != null)
      {
         _current.Dismiss()
         _current.NavigationMgr = null;
         _current = null;
      }

      if (nextPresenter != null)
      {
         _current = nextPresenter;
         _current.NavigationMgr = this;
         _current.Display(args);
      }         
   }

}


class MainMenuPresenter : Presenter
{

   private IMainMenuView _mainMenuView = null;

   // OnDisplay is your startup hook
   protected override void OnDisplay()
   {
      // get your view from where ever (injection, etc)
      _mainMenuView = GetView();      

      // configure your view
      _mainMenuView.Title = GetMainTitleInCurrentLanguage();
      // etc      
      // etc

      // listen for relevent events from the view
      _mainMenuView.NewWorkOrderSelected += new EventHandler(MainMenuView_NewWorkOrderSelected);

      // display to the user
      _mainMenuView.Show();
   }

   protected override void OnDismiss()
   {
      // cleanup
      _mainMenuView.NewWorkOrderSelected -= new EventHandler(MainMenuView_NewWorkOrderSelected);
      _mainMenuView.Close();
      _mainMenuView = null;
   }

   // respond to the various view events
   private void MainMenuView_NewWorkOrderSelected(object src, EventArgs e)
   {
      // example of transitioning to a new view here...
      NavigationMgr.NavigateTo(NewWorkOrderPresenter, null);            
   }

}


class NewWorkOrderPresenter : Presenter
{

   protected override void OnDisplay()
   {
      // get the view, configure it, listen for its events, and show it
   }

   protected override void OnDismiss()
   {
      // unlisten for events and release the view
   }

}
于 2012-10-23T12:38:18.880 に答える
2

私は長い間WinFormsを使用していませんが、これに答えようとします。私はWPFPrismと同じ戦略を使用します。

MainViewとApplication.Runについて:UserControlを保持できる空のコンテナーを含むメインリージョン(ルートフォーム)を作成し(正確なクラス名を忘れました)、ルートビューを切り替える必要がある場合は、RootView.SetView(UserControlビュー)を実行します。これは、Form.Clear()、Form.AddChild(view)のようなことをします。

ナビゲーションとコンテナの使用について:ナビゲーション用のサービスを作成できます:INavigationService.NavigateView(String(or Type)viewName、params object [] additionalData)のようなメソッドを使用してコンストラクターに挿入するINavigationService

于 2012-10-19T06:40:46.100 に答える
1

実際のフォームを返すメソッドをmainViewに挿入してから、を呼び出すことができます。

Mainview:IMainView 
{
        Form GetView()
        {
              //return new Form();
        }
 }

メインでは、を呼び出すことができます、

Application.Run(mainView.GetView())
于 2012-10-19T05:06:08.200 に答える