close window using dependency injection

Eduardo Gomez 3,416 Reputation points
2023-02-01T04:29:51.1233333+00:00

I have my dependency injection setup

public partial class App : Application {

    private readonly IHost _host;
    public App() {

        //For debuging purposes

        Thread.CurrentThread.CurrentUICulture = new CultureInfo("es");
        //Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");


        SyncfusionLicenseProvider.RegisterLicense(ConstantsHelpers.SYNCFUSION_KEY);

        _host = Host.CreateDefaultBuilder()
            .ConfigureServices((context, services) => {

                string? FireDomain = context.Configuration.GetValue<string>("FIREBASE_DOMAIN");
                string? FireKey = context.Configuration.GetValue<string>("FIREBASE_KEY");

                var config = new FirebaseAuthConfig {
                    ApiKey = FireKey,
                    AuthDomain = FireDomain,
                    Providers = new FirebaseAuthProvider[] {
                      new EmailProvider()
                    }
                };

                services.AddSingleton<IFirebaseAuthClient>(new FirebaseAuthClient(config));
                var serviceProvider = services.BuildServiceProvider();
                var firebaseAuthClient = serviceProvider.GetRequiredService<IFirebaseAuthClient>();
                if (firebaseAuthClient == null) {
                    throw new InvalidOperationException("IFirebaseAuthClient is not registered with the container.");
                }
                services.AddSingleton((services) => new SignUpLoginWondow(firebaseAuthClient));
                // Register another window
                services.AddSingleton((services) => new MainWindow());
            })
            .Build();
    }

    protected override void OnStartup(StartupEventArgs e) {

        MainWindow = _host.Services.GetRequiredService<SignUpLoginWondow>();
        MainWindow.Show();
        base.OnStartup(e);
    }

I have two Windows

Main Windows and SignUpLoginWindows

and the view Model for each one.

in my Sign in ViewModel, I want to close it when I logged back in or register

  private User? _user { get; set; }

        private readonly IFirebaseAuthClient _firebaseAuthClient;

        private bool isShowingRegister = false;

        public AsyncCommand RegisterCommand { get; set; }

        public Command LoginCommand { get; set; }

        public Command SwitchViewsCommand { get; set; }

        public LocalUser User { get; set; }

        public Visibility RegisterVis { get; set; }

        public Visibility LoginVis { get; set; }

        public SignUpLoginWondowViewModel(IFirebaseAuthClient firebaseAuthClient) {
            _firebaseAuthClient = firebaseAuthClient;
            User = new LocalUser();
            User.PropertyChanged += (sender, args) => RegisterCommand?.RaiseCanExecuteChanged();
            RegisterCommand = new AsyncCommand(RegisterActionAsync, CanRegster);
            LoginCommand = new Command(LoginAction, CanLogin);
            LoginWithSavedData();
            SwitchViewsCommand = new Command(SwitchViews);


            LoginVis = Visibility.Visible;
            RegisterVis = Visibility.Collapsed;
        }

        private bool CanRegster(object arg) {
            if (!string.IsNullOrEmpty(User.Email)
                && !string.IsNullOrEmpty(User.Password)
                && !string.IsNullOrEmpty(User.Username)
                && !string.IsNullOrEmpty(User.Confirm)
                && User.Confirm == User.Password
                && User.Password.Length == 6
                && new EmailAddressAttribute().IsValid(User.Email)) {
                return true;
            }
            return false;
        }

        private async Task RegisterActionAsync() {

            try {
                var result = await _firebaseAuthClient.CreateUserWithEmailAndPasswordAsync(User.Email, User.Password, User.Username);
                if (result.User != null) {
                    _user = result.User;
                    // Save user data in a local file
                    string userDataFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "userdata.json");
                    File.WriteAllText(userDataFile, JsonSerializer.Serialize(_user));
                    MainWindow mainWindow = new();
                    mainWindow.Show();
                }
            } catch (FirebaseAuthException ex) {
                var message = ex.Message;
                var startIndex = message.IndexOf("Response: ") + "Response: ".Length;
                var endIndex = message.IndexOf("\n\nReason");
                var jsonString = message[startIndex..endIndex];
                var error = JsonSerializer.Deserialize<FirebaseResponse>(jsonString);
                switch (error!.error.message) {

                    case "EMAIL_EXISTS":
                        MessageBox.Show(Lang.EMAIL_EXISTS);
                        break;

                    case "INVALID_EMAIL":
                        MessageBox.Show(Lang.INVALID_EMAIL);
                        break;

                }
            }
        }

        private static void LoginWithSavedData() {
            string userDataFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "userdata.json");
            if (File.Exists(userDataFile)) {
                var savedUser = JsonSerializer.Deserialize<FireUser>(File.ReadAllText(userDataFile));
                if (!string.IsNullOrEmpty(savedUser!.Uid)) {
                    MainWindow mainWindow = new();
                    mainWindow.Show();

     Application.Current.Windows[0].Close();
                }
            }
        }

The problem is here

  protected override void OnStartup(StartupEventArgs e) {

        MainWindow = _host.Services.GetRequiredService<SignUpLoginWondow>();
        MainWindow.Show();
        base.OnStartup(e);
    }

I get this error, and for some reason is in Spanish

System.InvalidOperationException: 'No se puede establecer Visibility ni llamar a Show, ShowDialog o WindowInteropHelper.EnsureHandle después de haberse cerrado un element Window.'

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,681 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hui Liu-MSFT 40,786 Reputation points Microsoft Vendor
    2023-02-01T06:51:46.9666667+00:00

    System.InvalidOperationException: 'No se puede establecer Visibility ni llamar a Show, ShowDialog o WindowInteropHelper.EnsureHandle después de haberse cerrado un element Window.'

    This is what it is. Practically, you cannot use a window after it was closed.

    The usual practice is this: handle the event Closing or override the protected virtual method OnClosing to cancel closing and hide the window instead. In this way, you will be able to show this instance of the window again. To cancel closing, you will need to assign true to the property Cancel of the event arguments parameter. You could refer to CancelEventArgs Class .


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful