2

これは、私の WPF アプリケーションの App コンストラクターです。

public partial class App
{
    public App()
    {
        Run(new Login(false));
    }


}

そして、これは私のログインコンストラクターです:

public Login(bool ignoreSettings)
    {
        InitializeComponent();
        if (ignoreSettings)
        {
            TxtUsername.Text = SettingsSaver.LoadUsername();
            TxtCrmUrl.Text = SettingsSaver.LoadCrmUrl();
            return;
        }
        if (string.IsNullOrWhiteSpace(SettingsSaver.LoadUsername()) || string.IsNullOrWhiteSpace(SettingsSaver.LoadCrmUrl())) return;
        try
        {
            CrmConnector.ConnectToCrm();
            MainWindow mainWindow = new MainWindow();
            mainWindow.Show();
        }
        catch (SecurityAccessDeniedException)
        {
            MessageBox.Show(@"Uw inloggegevens zijn niet correct. Gelieve deze te controleren en opnieuw te proberen.");
        }
        finally
        {
            Close();
        }
    }

App コンストラクターを開始し、Login コンストラクターを問題なく通過しますが、Login コンストラクターの終了後に再び App コンストラクターに到達すると、追加情報と共に InvalidOperationException でクラッシュします。ウィンドウが閉じられた後の.EnsureHandle。

コンストラクターの目的は次のとおりです。アプリケーションが最初に開始されたときに、このアプリケーションの既存の設定があるかどうかを確認したいと考えています。存在する場合は、それらの設定を使用してサード パーティ (Dynamics CRM 2011) に接続し、アプリケーションのメイン ウィンドウを開いて、ログイン画面を閉じます。そこにない場合は、ユーザーに設定してもらいたいです。

ただし、メイン画面のボタンからこのウィンドウを起動できるようにしたいのですが、その場合、デフォルト設定を無視してログインウィンドウを再度起動し、設定を再度設定できるようにする必要があります。

私はすでに2つのコンストラクターを使用して動作させることができましたが、2番目のコンストラクター(メイン画面のボタンから起動するコンストラクター)のパラメーターを基本的に無視するため、Resharperはそれを行うと文句を言います。統一されたコンストラクターなので、Resharper は文句を言いません。

編集: MainWindow で次のコードを使用して、設定を変更すると新しいウィンドウが作成されるため、ログイン ウィンドウを保持したくありません。

private void BtnSettings_Click(object sender, RoutedEventArgs e)
    {
        Login login = new Login(true);
        login.Show();
        Close();
    }

編集:いくつかの明確化:複数のウィンドウを表示したくありません。私が欲しいのは:

  1. 起動時に Login.xaml を起動します。
  2. Login.xaml の起動時に、設定が既に設定されているかどうかを確認します。
  3. 設定がない場合は、設定のために Login.Xaml を表示します。
  4. 設定が設定されている場合は、保存された設定で MainWindow を起動します。

さらに、Login.xaml を強制的に起動する必要がある MainWindow のボタンがありますが、設定があるかどうかは確認しません。これらは現在別々のコンストラクターであり、それらの 1 つのコンストラクターを作成したいと思います。

4

4 に答える 4

2

あなたの更新により、達成したいことが少し明確になります。Loginウィンドウを再構築して、ウィンドウをより単一の責任にし、検証ロジックをAppクラスにプッシュして、初期化フローの管理を担当するようにすることをお勧めします。レシピは次のとおりです。

App.Xaml.csのように変更します。重要なことはありませんStartupUri

<Application 
    x:Class="MyNamespace.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources />
</Application>

クラスMyNamespaceの名前空間はどこにありますか。App

ここで、アプリケーションを手動で開始します。App.OnStartup

public partial class App
{
    protected override void OnStartup(System.Windows.StartupEventArgs e)
    {
        base.OnStartup(e);

        if (!AreSettingsSet())
        {
            this.MainWindow = new Login();
            this.MainWindow.ShowDialog(); // Waits until closed.

            // Recheck the settings now that the login screen has been closed.
            if (!AreSettingsSet())
            {
                // Tell the user there is a problem and quit.
                this.Shutdown();
            }
        }

        this.MainWindow = new MainWindow();
        this.MainWindow.Show();
    }

    private bool AreSettingsSet()
    {
        // Whatever you need to do to decide if the settings are set.
    }
}

要約すると、Loginウィンドウから検証ロジックを削除し、必要な場合にのみ表示Appし、設定が実際に有効である場合にのみ表示します。LoginMainWindow

于 2014-04-29T13:39:24.550 に答える
0

保持したい場合は、Close の代わりに Visibility.Hidden を試してください

更新: this.Visibility=Visibility.Hidden;

于 2014-04-29T11:27:55.377 に答える
0

微調整を行う必要があります。その後、複数のウィンドウまたは単一のウィンドウを複数回表示できます。

  1. StartupUriApp.xaml から削除します。
  2. PageApp.xaml のBuild アクションをに設定します。

これにより、App.g.ics の自動生成が無効になり、独自のアプリケーション エントリ ポイントを作成できます。

public partial class App : Application
{
    [STAThread]
    public static void Main()
    {
        App app = new App();
        app.InitializeComponent();
        app.ShowWindow1();
        app.ShowWindow1(); // show second time same window (new instance)
    }

    public void ShowWindow1()
    {
        // show window1 in separate method, so that instance will be deleted after method ends
        Window1 window1 = new Window1();
        // optional (as it seems)
        // MainWindow = window1
        widow1.Show();
    }
}
于 2014-04-29T12:28:15.360 に答える