【问题标题】:(WPF) Does .Close() method releases the window instance?(WPF) .Close() 方法是否释放窗口实例?
【发布时间】:2021-02-21 16:20:05
【问题描述】:

我正在 On_Click 方法中创建一个新窗口。首先我尝试了这个;

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();
    }
}

它不起作用,所以每次用户单击“客户”按钮时,我都开始创建窗口实例。我使用了以下代码。

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

在新窗口中,如果用户点击主按钮,我想导航到主窗口。

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

第一个问题:this.Close() 是否释放窗口实例?

第二个问题:这种用法正确吗?

您认为最佳做法是什么?

谢谢大家。

【问题讨论】:

    标签: wpf navigation window


    【解决方案1】:

    Window.Close() 将释放实例分配的所有资源。这就是为什么一旦关闭就无法再次显示它的原因。

    如果你想重用同一个Window实例,你应该取消关闭过程以防止内部资源被处置并折叠窗口(通过将Window.Visibility设置为Visibility.Collapsed - Visibility.Collapsed也是默认值在调用 Window.Show() 之前实例化的 Window 的值)。

    也可以通过调用Window.Hide()(将Visibility 设置为Visibility.Hidden)而不是Window.Close() 来隐藏Window

    调用Window.Show 也会将窗口的可见性设置为Visibility.Visible
    事实上,通过设置Window.Visibility 显示WindowWindow.Show() 的异步版本。

    通常,您使用Window.Activate 方法在Window 实例之间切换。在当前显示/可见的 Window 上调用 Window.Show 不会执行任何操作。

    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();
        }
    }
    

    创建 Window 实例会分配非托管资源。如果这种情况经常发生,您将使垃圾收集器保持忙碌状态。从性能的角度来看,您可能希望避免它并更愿意重用相同的实例。
    在常见情况下,这不是必需的。但是由于Window暴露了Hide()方法,你可以考虑使用它来代替Close()

    【讨论】:

      【解决方案2】:

      如果要切换到父窗口,可以使用代码this.Owner.Activate();,如果要关闭当前窗口,先this.Owner.Activate();this.Close();

      当您输入this.Close() 时,编译器在到达它后不会执行以下行。当示例窗口仍然存在时,无需重新创建它

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-02
        • 2016-10-03
        • 2022-01-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多