c# – 在ViewModelViewHost控件中托管的View和ViewModel中使用时调用两次WhenActivated

前端之家收集整理的这篇文章主要介绍了c# – 在ViewModelViewHost控件中托管的View和ViewModel中使用时调用两次WhenActivated前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的应用程序使用视图,这些视图实现了IViewFor< T>接口.视图已在AppBootstrapper中的依赖项解析程序中注册.应用程序通过为控件的viewmodel属性指定相应的视图模型,使用viewmodelViewHost控件显示视图.所有视图模型都实现了ISupportsActivation接口.

我注意到WhenActivated被调用了两次.首先,当视图和视图模型被激活时调用它.然后在停用时,丢弃所有一次性用品,然后立即再次调用WhenActivated,然后处理一次性用品.

我在视图和视图模型中使用以下代码进行测试:

this.WhenActivated(disposables =>
{
    Debug.WriteLine("viewmodel activated.");

    Disposable
        .Create(() =>
        {
            Debug.WriteLine("viewmodel deactivated.");
        })
        .AddTo(disposables);
});

结果输出如下:

// App displays the view:

viewmodel activated.
View activated.

// App hides the view:

viewmodel deactivated.
View deactivated.
viewmodel activated.
View activated.
viewmodel deactivated.
View deactivated.

通过将viewmodelViewHost控件的viewmodel属性设置为null来隐藏视图.

难道我做错了什么?

编辑:这是完整的源代码https://gist.github.com/dmakaroff/e7d84e06e0a48d7f5298eb6b7d6187d0

按第一个Show然后按Hide按钮将产生以下输出

Subviewmodel activated.
SubView activated.
Subviewmodel deactivated.
SubView deactivated.
Subviewmodel activated.
SubView activated.
Subviewmodel deactivated.
SubView deactivated.

解决方法

SubView中使用的WhenActivated调用返回一个IDisposable对象,该对象可以在WhenActivated的同一调用中使用,以在停用时从激活事件中删除您的订阅.这样做可以防止二次激活和处理.

在SubView构造函数中,更改此:

this.WhenActivated(d =>
{
    Debug.WriteLine("SubView activated.");
    d(Disposable.Create(() => { Debug.WriteLine("SubView deactivated."); }));

    d(this // viewmodel -> DataContext
        .WhenAnyValue(v => v.viewmodel)
        .BindTo(this,v => v.DataContext));
});

对此:

System.IDisposable whenActivatedSubscription = null;
whenActivatedSubscription = this.WhenActivated(d =>
{
    Debug.WriteLine("SubView activated.");
    d(Disposable.Create(() => { Debug.WriteLine("SubView deactivated."); }));

    d(this // viewmodel -> DataContext
        .WhenAnyValue(v => v.viewmodel)
        .BindTo(this,v => v.DataContext));
    d(whenActivatedSubscription); // <- Dispose of the activation subscription here
});

这样做的原因是,由于您的视图被销毁/处置,因此激活订阅本身也需要作为此过程的一部分进行处理.

原文链接:https://www.f2er.com/csharp/91780.html

猜你在找的C#相关文章