6

Caliburn.Microは初めてですが、アプリケーションでユーザーのログイン/ログアウトサイクルを処理するための最良の方法は何でしょうか。LoginViewとメインアプリケーションビューを切り替える空のShell-Viewを使用してこれを実装するためのいくつかの提案をオンラインで見ました。もちろん、それぞれにカスタムViewModelがあります。

私にとって、これらは非常に異なるプロパティ(タイトル、アイコン、サイズ)を持つ2つの別々のウィンドウであり、2つが一方のウィンドウをもう一方のウィンドウのように変更するのは汚れた解決策のように見えるため、このソリューションはあまり好きではありません。もう1つの問題は、ログインウィンドウが、私が制御しておらず、Caliburn.Microを使用していないユーティリティライブラリからのものであるということです。これは、ユーザーが[ログイン]をクリックしたときにイベントを表示する古いウィンドウです。

Bootstrapperの起動方法でこのダイアログを表示する提案も見ましたが、問題は、ユーザーがアプリケーションの「ログアウト」を選択して、ログインダイアログを再度表示できることです。Bootstrapperでビュー間の切り替えを処理するのは間違っているようです。

Caliburn Conductorのように機能する何らかのApplicationViewModelまたはApplicationControllerが必要ですが、ウィンドウ内のビューを切り替える代わりに、LoginWindowとMainWindowを切り替え、アプリケーション全体のクローズも処理する必要があります(これはログアウトも必要です)。アクティベーション時に、LoginWindowが表示され、Loginイベントが処理されてから、メインウィンドウ(シェル)に切り替わります。ユーザーが「ログアウト」を選択した場合、イベントは再びApplicationViewModel / Controllerにバブルアップし、メインウィンドウを非アクティブ化/閉じ、ログアウトを実行してから、LoginDialogを再度表示します。同様に、Closeイベントはログアウトを実行しますが、アプリケーション全体をシャットダウンします。

だから私の質問は:

  1. このソリューションについてどう思いますか?また、別の/より良いソリューションがありますか?
  2. これを実装するにはどうすればよいですか?;-)

どうもありがとう!

4

2 に答える 2

19

あなたの問題の解決はかなり簡単だと思います。

一言で言えば、アプリケーションの起動時にログインウィンドウで表されるシェルとして1つのViewModelを作成しています。ユーザーが正常にログインすると、このウィンドウが閉じ、viewModelの同じインスタンスがコンテンツウィンドウに表示されます。ユーザーがログアウトしている場合は、ログインウィンドウが再度表示されます。

まず、2つのデリゲートを公開するインターフェイスIShellを作成しますLoginSuccessfulLogout

public interface IShell
    {
        Action LoginSuccessful { get; set; }
        Action Logout { get; set; }
    }

次に、ShellViewModel実装するクラスを作成しますIShell

 public class ShellViewModel : Screen, IShell
    {
        public ShellViewModel()
        {
            LoginSuccessful = delegate { };
            Logout = delegate { };
        }

        public Action LoginSuccessful { get; set; }
        public Action Logout { get; set; }

        public void DoLogin()
        {
            LoginSuccessful();
        }

        public void DoLogout()
        {
            Logout();
        }
    }

メソッドDoLoginとは、または適切なコントロールDoLogoutにバインドできるアクションです。Button

OnStartupMethod次のステップは、Bootstrapperでをオーバーライドすることです。この前提条件は、のインスタンスがありWindowManagerShellViewModel選択したIoCフレームワークによってエクスポートされます。

protected override void OnStartup(object sender, StartupEventArgs e)
        {
            var windowManager = IoC.Get<IWindowManager>();
            var viewModel = IoC.Get<IShell>();

            viewModel.LoginSuccessful =
                () => GuardCloseAndReopen("Content");

            viewModel.Logout =
                () => GuardCloseAndReopen("Login");

            windowManager.ShowWindow(viewModel, "Login");
        }

        private void GuardCloseAndReopen(string shellViewMode)
        {
            var windowManager = IoC.Get<IWindowManager>();
            var shellScreen = IoC.Get<IShell>() as Screen;

            Application.ShutdownMode = ShutdownMode.OnExplicitShutdown;

            shellScreen.TryClose();

            Application.ShutdownMode = ShutdownMode.OnLastWindowClose;

            windowManager.ShowWindow(shellScreen, shellViewMode);
        }

これに対する秘訣は次のとおりです。DoLogoutメソッドが呼び出された場合、を呼び出すことによって現在のウィンドウが閉じられTryCloseますShellViewModel。同時に、をに設定することにより、アプリケーションがシャットダウンされないようにしApplication.ShutdownModeますOnExplicitShutdown。次に、windowmanagerを使用して、コンテキスト情報として「Login」をwindowManagerに渡すことにより、ログインモードで別のウィンドウを作成します。これは実際には同じViewModelですが、視覚的な表現が異なります。

あなたはLogoutちょうど周りで同じことをしているからです。

Caliburnコンベンションを使用してこれを機能させるには、ここに示されている(そしてそこで説明されている) 特別なプロジェクト構造が必要です。ここに画像の説明を入力してください

ここで、このコードを使用して、小さなサンプルアプリケーションを作成するようにお願いします。ビューを作成しLogin(ボタンなどでログインします)Content、LoginSuccessful/Logoutメソッドを使用してログアウトボタンでビューを作成します。

これにより、最小限のコードとクラスで問題が解決します。これがお役に立てば幸いです。

于 2012-08-17T21:02:04.053 に答える
3

私は基本的には機能するものを作成することに挑戦しましたが、実際に使用するにはもう少し作業が必要になるでしょう。完全なコメントとソースは、私のWebサイトのこの投稿Caliburn.MicroLoginWindowサンプルにあります。

Caliburn.Microを使用してIEventAggregator、2つのウィンドウ間の遷移を制御しました。ログイン画面を開くには、次のコードを取得します。

public void Handle(LoginEvent message)
{
    LoginWindow loginWindow = new LoginWindow();
    loginWindow.Login += new EventHandler<LoginEventArgs>(this.LoginWindow_Login);
    loginWindow.Cancel += new EventHandler(LoginWindow_Cancel);
    loginWindow.ShowDialog();
}

この同じソースは、アプリを初めて開いたときとログアウトイベントが公開されたときの両方で使用されます。ログアウトイベントは次のようになります。

public void Handle(LogoutEvent message)
{
    Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
    message.Source.TryClose();
    Application.Current.ShutdownMode = ShutdownMode.OnLastWindowClose;
    this.events.Publish(new LoginEvent());
}

ログインが成功すると、次のコードを使用して、ViewModelに基づくメインウィンドウが開きます。

ContentViewModel viewModel;
viewModel = IoC.Get<ContentViewModel>();
viewModel.Username = e.Username;
this.windowManager.ShowWindow(viewModel);
于 2012-08-22T19:42:42.427 に答える