c# - WhenActivated 在 ViewModelViewHost 控件中托管的 Views 和 ViewModel 中使用时被调用两次

标签 c# .net wpf reactiveui

我的应用使用 View ,它实现了 IViewFor<T>界面。这些 View 已在 AppBootstrapper 中的依赖项解析器中注册.该应用程序使用 ViewModelViewHost 显示 View 通过将相应的 View 模型分配给控件的 ViewModel 来进行控制属性(property)。所有 View 模型都实现了 ISupportsActivation界面。

我注意到 WhenActivated被调用两次。首先,当 View 和 View 模型被激活时它被调用。然后在停用时处理所有一次性用品并且WhenActivated立即再次调用,然后处理一次性用品。

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

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 来隐藏 View 。

我做错了什么吗?

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

先按显示然后按隐藏按钮会产生以下输出:

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

此解决方案之所以有效,是因为您的 View 正在被销毁,因此激活本身也需要作为此过程的一部分进行处理。

关于c# - WhenActivated 在 ViewModelViewHost 控件中托管的 Views 和 ViewModel 中使用时被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36433709/

相关文章:

c# - 在没有空格键的情况下计算字符串中的字母

.net - 如何动态加载单独的应用程序设置文件并与当前设置合并?

.NET 编译器 - 来自非托管 C++ 的 CLR 程序集元数据访问/反射

.net - 在 SharePoint 搜索页面中同时更新面板、JavaScript 回发和更改查询字符串

c# - 这段 RxUI 代码有什么问题?

c# - 为什么 VS 11 中的按钮点击速度很慢,如何解决?

c# - 如何为 Azure Functions 配置 NLog?

c#mvc区域文件夹结构和类名

c# - 访问 Web 用户控件中的类变量

c# - 在 silverlight 中添加自定义字体