c# - ReactiveUI命令退订

标签 c# .net wpf mvvm reactiveui

我有2个 View 和2个ViewModel:

第一 View :

public partial class FirstView : Page
{
    FirstViewModel ViewModel;
    public FirstView()
    {
        ViewModel = new FirstViewModel();
        ViewModel.ShowSecondView.Subscribe(_ =>
        {              
            NavigationService.Navigate(new SecondView(ViewModel.ChildViewModel));
        });            

        this.DataContext = ViewModel;
        InitializeComponent();            
    }        
}

第一个ViewModel:
public class FirstViewModel
{
    SecondViewModel ChildViewModel;
    public ReactiveCommand<Unit, Unit> ShowSecondView { get; set; }
    public FirstViewModel()
    {
        ChildViewModel = new SecondViewModel();
        ShowSecondView = ReactiveCommand.Create(() => 
        {
             ChildViewModel.Reconfigure(...);  
        });          
    }        
}

第二种观点:
public partial class SecondView : Page
{
    SecondViewModel ViewModel;
    public SecondView(SecondViewModel viewModel)
    {
        ViewModel = viewModel;
        ViewModel.GoBack.Subscribe(_ => 
        {
            DoSomethingHard();
            if(NavigationService != null)  NavigationService.GoBack();
        });
        this.DataContext = ViewModel;
        InitializeComponent();            
    }        
}

第二个ViewModel:
public class SecondViewModel
{
    public ReactiveCommand<Unit, Unit> GoBack { get; set; }
    public FirstViewModel()
    {
        VeryLongInitialization();
        GoBack = ReactiveCommand.Create(() => { });          
    }        
    public void Reconfigure(...)
    { ... }
}

因此,当我多次运行FirstViewModel.ShowSecondView和多次运行SecondViewModel.GoBack时,DoSomethingHard()在每个创建的SecondView上也执行了多次。

为什么我要一次在ChildViewModel中创建FilstViewModel?因为创建SecondViewModel需要很长时间。而且我不会每次都重新创建SecondViewModel,而只是重新配置它。

我的问题是如何取消订阅ViewModel.GoBack.Subscribe中的SecondView

附言也许我不应该在SecondView中重新创建FirstView,而要像SecondViewModel一样重新配置它?

更新1 (感谢Julien Mialon)

我添加IDisposable goBackSubscr,它可以工作!我执行它正确吗?
public partial class SecondView : Page
{
    SecondViewModel ViewModel;
    IDisposable goBackSubscr;
    public SecondView(SecondViewModel viewModel)
    {
        ViewModel = viewModel;
        goBackSubscr = ViewModel.GoBack.Subscribe(_ => 
        {
            DoSomethingHard();
            if(NavigationService != null)  NavigationService.GoBack();
            goBackSubscr.Dispose();
        });
        this.DataContext = ViewModel;
        InitializeComponent();            
    }        
}

最佳答案

在您的 View 上使用WhenAcitvated:
在页面的构造函数中(必须为IViewFor):

 this.WhenActivated(
     disposables =>
     {
         ViewModel.Command.Subscribe(...).(disposables);
     });

关于c# - ReactiveUI命令退订,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47674284/

相关文章:

c# - 重定向到 URL - asp.net 与 MVC

c# - 创建 RIA 服务 DomainContext 的最佳实践

Adobe PDF 中的 JavaScript 执行

c# - 程序集内的多个系统

c# - 更改时如何知道 ContentControl 的内容何时加载

WPF,将 Path.DataProperty 转换为 Segment 对象

c# - 使用 "extra"变量是否错误,因为它更容易调试?

.net - WCF:使用相同的代码来实现 SOAP 和 JSON?

c# - .NET 命令行参数错误?

.net - mvvm-light 工具包未触发 Window Loaded 事件