当被激活时不开火

时间:2017-08-31 14:21:16

标签: c# reactiveui

我正在使用ReactiveUI构建一个应用程序,并且我正在使用WhenActivated订阅在我的ViewModel上加载一些值,但我面临的情况是它不会被解雇:

Select()

除非我为此更改View构造函数,否则不会触发LoadDataAsync:

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

这样一切都按预期工作。这是为什么?有没有办法避免记住每个窗口上的所有“WhenActivated”?

1 个答案:

答案 0 :(得分: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()手动激活VM(并在你想要停用时处理返回值),但是我猜这种方式会失败。