简体   繁体   English

在哪里取消订阅活动?

[英]Where to unsubscribe from events?

Eg for a general type, which subscribe to some events in constructor:例如,对于一般类型,它订阅构造函数中的一些事件:

class SomeType
{
    public SomeType(...)
    {
        someEvent1 += ...
        someEvent2 += ...
    }
}

Where do I unsubscribe from events?我在哪里取消订阅活动?

  • Finalizer?终结者?
  • IDisposable ?我是IDisposable
  • Some method DontForgetToCallMeSoICanUnsubscribeFromEvents() ?一些方法DontForgetToCallMeSoICanUnsubscribeFromEvents()
  • Use weak events pattern?使用弱事件模式?

I know it depends .我知道这取决于 In case of controls (wpf, winforms) there are some events what can be used to subscribe/unsubscribe like Loaded / Unloaded , HandleCreated / HandleDestroyed , etc. But what if parent is a simple object ?在控件(wpf、winforms)的情况下,有一些事件可用于订阅/取消订阅,如Loaded / UnloadedHandleCreated / HandleDestroyed等。但是如果 parent 是一个简单的object怎么办?

And some more specific example: nested ViewModels, where each level is a List<NextLevelVM> , at any level ViewModel can be deleted, does that means what each ViewModel must implement IDisposable (if eg it is the right way) where it call Dispose for each item in their list?还有一些更具体的例子:嵌套的 ViewModels,其中每个级别都是一个List<NextLevelVM> ,在任何级别 ViewModel 都可以被删除,这是否意味着每个 ViewModel 必须实现IDisposable (如果它是正确的方法),它调用Dispose用于他们列表中的每个项目? I tried to use weak events, but that doesn't go well .我尝试使用弱事件,但效果不佳 go

I've found a really good way to handle this issue is to create two methods in the page's code behind, that calls methods on your ViewModel to start/stop listening to events depending on whether it's visible or not.我发现处理这个问题的一个非常好的方法是在页面的后台代码中创建两个方法,调用 ViewModel 上的方法以根据事件是否可见来开始/停止侦听事件。

Below I'm using the Appearing functions, but depending on the framework you're using it might be slightly different, but the strategy should work.下面我使用的是 Appearing 函数,但根据您使用的框架,它可能会略有不同,但该策略应该有效。

In Page class:在页面 class 中:

protected override void OnAppearing()
{
    base.OnAppearing();
    _myViewModel.StartListeningToEvents();
}

protected override void OnDisappearing()
{
    base.OnDisappearing();
    _myViewModel.StopListeningToEvents();
}

Then in my ViewModel, I actually subscribe to the events I require:然后在我的 ViewModel 中,我实际上订阅了我需要的事件:

public void StartListeningToEvents()
{
    SomeProperty.PropertyChanged += PropertyUpdated;
}

public void StopListeningToEvents()
{
    SomeProperty.PropertyChanged -= PropertyUpdated;
}

void PropertyUpdated(object sender, PropertyChangedEventArgs e)
{
    // do stuff
}

My example is for a property change event.我的示例是针对属性更改事件的。 But similar code should work for any event.但是类似的代码应该适用于任何事件。

In this way you're guaranteed that your page is only listening to events when it's open, and you don't need to worry about disposing anything besides calling the one event when the page is no longer open.通过这种方式,您可以保证您的页面仅在打开时监听事件,并且您无需担心除了在页面不再打开时调用一个事件之外处理任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM