Search code examples
wpfnavigationwindow

(WPF) Does .Close() method releases the window instance?


I'm creating a new window in On_Click method. First I tried this;

public partial class MainWindow : Window
{
    CustomerOperations customerOperationsWindow;
    public MainWindow()
    {
        customerOperationsWindow = new CustomerOperations();
        InitializeComponent();
    }

    private void btnCustomer_Click(object sender, RoutedEventArgs e)
    {
        customerOperationsWindow.Owner = this;
        customerOperationsWindow.Show();
    }
}

It's not working so I started creating the window instance every time the user clicks on the Customers button. And I used the following codes.

 private void btnCustomer_Click(object sender, RoutedEventArgs e)
    {
        CustomerOperations customerOperationsWindow = new CustomerOperations();
        customerOperationsWindow.Owner = this;
        customerOperationsWindow.Show();
    }

In the new window, If user clicks to Main button, I want to navigate to main window.

private void btnMain_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
        this.Owner.Show();
    }

First question: Does this.Close() releases the window instance?

Second question: Is this usage correct?

What do you think is the best practice?

Thank you all.


Solution

  • Window.Close() will dispose all resources allocated by the instance. That's why you cannot show it again once it was closed.

    If you want to reuse the same Window instance, you should cancel the closing procedure to prevent disposal of internal resources and collapse the Window instead (by setting Window.Visibility to Visibility.Collapsed - Visibility.Collapsed is also the default value of an instantiated Window before Window.Show() is called).

    Alternatively hide the Window by calling Window.Hide() (which will set the Visibility to Visibility.Hidden) instead of Window.Close().

    Calling Window.Show will also set the window's visibility to Visibility.Visible.
    As a matter of fact, showing a Window by setting Window.Visibility is the asynchronous version of Window.Show().

    Generally, you switch between Window instances by using the Window.Activate method. Calling Window.Show on a Window that is currently showing/visible, does nothing.

    public partial class MainWindow : Window
    {
        CustomerOperations CustomerOperationsWindow { get; }
    
        public MainWindow()
        {
            InitializeComponent();
            this.CustomerOperationsWindow = new CustomerOperations();
    
            // Consider to move this logic to CustomerOperations class,
            // where you can override the OnClosing method instead of subscribing to the event
            this.CustomerOperationsWindow.Closing += CollapseWindow_OnClosing;
        }
    
        // Cancel close  to prevent disposal and collapse Window instead
        private void CollapseWindow_OnClosing(object sender, CancelEventArgs e)
        {
          e.Cancel = true;
          this.CustomerOperationsWindow.Visibility = Visibility.Collapsed;
          this.CustomerOperationsWindow.Owner.Activate();
        }
    
        private void btnCustomer_Click(object sender, RoutedEventArgs e)
        {
            this.CustomerOperationsWindow.Owner = this;
    
            // Calling Show will set the Visibility to Visibility.Visible
            this.CustomerOperationsWindow.Show();
        }
    }
    

    Creating a Window instance allocates unmanaged resources. If this happens very frequently, you will keep the garbage collector busy. From a performance point of view you may want to avoid it and prefer to reuse the same instance.
    In a common scenario this is not necessary. But since Window exposes a Hide() method, you may consider to use it instead of Close().