2017-08-31 141 views
0

我建立与ReactiveUI一个应用程序,我装上使用WhenActivated订阅我的ViewModel一些值,但我面对这种情况下它不会被解雇:WhenActivated没有发射

public class MyWindow : Window, IViewFor<MyViewModel> 
{ 
    public MyViewModelViewModel 
    { 
     get => DataContext as MainWindowViewModel; 
     set => DataContext = value; 
    } 

    object IViewFor.ViewModel 
    { 
     get => DataContext; 
     set => DataContext = value; 
    } 

    public MyView() 
    { 
     this.DataContext = new MyViewModel(); 
    } 
} 

public class MyViewModel : ReactiveObject 
{ 
    public MyViewModel() 
    { 
     this.WhenActivated(d => LoadDataAsync().ToObservable().Subscribe(
       res => { }, 
       exc => 
       { 
        Debug.WriteLine("Error ocurred on InitAsync: " + exc.Message + " - " + exc.StackTrace); 
        //HANDLE EXCEPTION 
       } 
       ).DisposeWith(d)); 
    } 

    private async Task LoadDataAsync() => await DataBase.LoadData(); 
} 

LoadDataAsync不会被解雇,除非我改变视图构造函数是:

public MyView() 
{ 
    this.DataContext = new MyViewModel(); 

    //If we dont' call WhenActivated on View it doesn't get called on ViewModel 
    this.WhenActivated(d => { }); 
} 

这样,一切正常。这是为什么?有没有办法避免记住每个窗口上的所有“WhenActivated”?

回答

0

您可能必须在您的视图模型上实现ISupportsActivation

public class MyViewModel : ReactiveObject, ISupportsActivation 
{ 
    public MyViewModel() 
    { 
     this.WhenActivated(d => LoadDataAsync().ToObservable().Subscribe(
       res => { }, 
       exc => 
       { 
        Debug.WriteLine("Error ocurred on InitAsync: " + exc.Message + " - " + exc.StackTrace); 
        //HANDLE EXCEPTION 
       } 
       ).DisposeWith(d)); 
    } 

    private async Task LoadDataAsync() => await DataBase.LoadData(); 

    // Add this property to implement the interface 
    public ViewModelActivator Activator { get; } = new ViewModelActivator(); 
} 

这明确地告诉RxUI您的VM支持激活。我通常把这个视图模型基类:

public class ViewModelBase : ReactiveObject, ISupportsActivation 
{ 
    public ViewModelActivator Activator { get; } = new ViewModelActivator(); 
} 

更新

据为ISupportsActivation在源代码中的注释,你必须调用WhenActivated在您的视图,使它工作。

或者,您可以通过调用MyViewModel.Activator.Activate()(并在您想停用时处置返回值)来手动激活虚拟机,但我猜测这种方式会使这一点失败。

+0

是的,这是缺少的问题,但实际上我有它在我的真实代码(忘了添加到示例),但它仍然不工作:( – rualmar

+0

我已更新我的答案与源代码中的细节基本上,您必须在视图中调用'WhenActivated'或手动激活VM –