使用MVVM中的dispose取消标记事件

Moe*_*bai 1 c# wpf mvvm

实际上我试图通过从我的手中解雇事件来关闭我的窗口ViewModel.一切都很好,很棒,但我知道我必须取消我的事件,以避免内存泄漏.因此我实现了IDisposable接口,我在Dispose方法中取消了事件.

以下是我的代码:

public partial class MainWindow : Window, IDisposable
{
    private MainViewModel viewModel;
    public MainWindow()
    {
        InitializeComponent();
        DataContext = viewModel =  new MainViewModel();
        this.viewModel.RequestClose += CloseWindow;
    }

    void CloseWindow(object sender, EventArgs e)
    {
        this.Close();
    }

    public void Dispose()
    {
        ////here we need to unsubscribe the event
        this.viewModel.RequestClose -= this.CloseWindow;
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要知道的是:

  1. 这段代码是否正确
  2. GC将被调用,EXCUTE Dispose方法
  3. 有没有更好的方法来做这样的事情

Den*_*nis 5

但我知道我必须取消记录我的事件以避免内存泄漏

当短期对象订阅长期存在的对象(或静态事件)事件时,会发生内存泄漏,并且以后不会取消订阅(例如,请参阅答案).我想,这不是你的情况.

当GC被调用并执行dispose方法时

GC不会调用IDisposable.Dispose(例如,请参阅答案).完全没有.如果你没有任何MainWindow.Dispose明确调用的代码,那么它将永远被调用.

有没有更好的方法来做这样的事情

我会避免IDisposable和事件.这里的附加行为更方便,IMO(至少,这是可重用的):

public static class WindowClosingBehavior
{
        public static bool GetIsClosingInitiated(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsClosingInitiatedProperty);
        }

        public static void SetIsClosingInitiated(DependencyObject obj, bool value)
        {
            obj.SetValue(IsClosingInitiatedProperty, value);
        }

        public static readonly DependencyProperty IsClosingInitiatedProperty = DependencyProperty.RegisterAttached(
            "IsClosingInitiated", 
            typeof(bool), 
            typeof(WindowClosingBehavior),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsClosingInitiatedChanged));

        private static void IsClosingInitiatedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            var window = target as Window;
            if (window != null && (bool)e.NewValue)
            {
                window.Close();
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

在窗口的XAML中的某个地方:

behaviors:WindowClosingBehavior.IsClosingInitiated="{Binding IsClosingInitiated}"
Run Code Online (Sandbox Code Playgroud)

IsClosingInitiated视图模型中的属性在哪里:

public class SomeViewModel
{
     // ...

     private void Foo()
     {
         // ...
         IsClosingInitiated = true;
     }
}
Run Code Online (Sandbox Code Playgroud)