什么是在ViewModel中解绑事件处理程序的正确方法

27 浏览
0 Comments

什么是在ViewModel中解绑事件处理程序的正确方法

我一直在研究如何正确地解除与视图模型相关的事件处理程序,以防止内存泄漏。\n假设我有一个如下所示的视图模型:\n

class MyViewModel
{
    private List _myObjects;
    public List MyObjects
    {
        get { return _myObjects; }
        set { _myObjects = value; }
    }
    public MyViewModel()
    {
        for (int i = 0; i < 10; i++)
        {
            var obj = new MyObject();
            obj.MySampleEvent += Obj_MySampleEvent;
        }
    }
    private void Obj_MySampleEvent(object sender, EventArgs e)
    {
        //做一些事情
    }
}

\n最初我找到了这个链接,其中说明了要实现`IDisposable`接口并添加一个`Dispose`方法:\n

public void Dispose()
{
    foreach (var obj in MyObjects)
    {
        obj.MySampleEvent -= Obj_MySampleEvent;
    }
}

\n但是当我期望调用它时,并不总是被调用。它似乎不稳定,有时甚至根本不会被调用?所以我决定搜索“何时调用Dispose”,这导致我找到了这个链接,解释说`Dispose`方法由`Finaliser`/`析构函数`调用。\n这引导我进行最后一项研究,即我记得有人说不要在`析构函数`中解除事件处理程序,因为它永远不会被调用,来自这个链接。\n所以我想最终澄清一下...在视图模型中解除事件处理程序的正确方法是什么?

0
0 Comments

原因:问题的出现是因为在ViewModel中订阅了一个事件,但没有正确地处理事件的取消绑定。

解决方法:正确的解决方法是在ViewModel中使用ObservableCollection来实现绑定,并直接在ViewModel属性上订阅事件。然后,在Window_Closing事件中进行清理操作。另外,在ViewModel对象上实现INotifyPropertyChanged接口,并将obj.PropertyChanged重定向到该接口。最后,需要注意在取消绑定时要正确地处理事件,以避免对应用程序的声誉产生负面影响。

0
0 Comments

问题的原因是在ViewModel中如何正确地取消事件处理程序的注册。解决方法是在导航期间,在OnNavigatedFrom事件中取消ViewModel上的事件处理程序的注册,然后在OnNavigatedTo事件中重新注册事件处理程序。关于IDisposable,作者表示不确定。他认为IDisposable用于管理资源而不是业务逻辑。他认为应该使用IDisposable的原因是,理想情况下,视图不应该知道视图模型来调用UnregisterEvents方法,因此需要一个接口,而已经存在接口IDisposable,其中包含一个Dispose方法,所以人们建议使用它。

0