ReactiveUI WhenActivated not firing

时间:2017-06-02 14:44:55

标签: c# xamarin mvvm xamarin.forms reactiveui

我尝试使用以下代码作为this帖子中建议的从我的viewmodel的构造函数中调用异步服务的安全方法。问题是,在this.WhenActivated火星的身体内,没有任何想法,为什么?

这是我的代码:

class MainViewModel : ReactiveObject, ISupportsActivation, IMainViewModel
{
    private IDataService _dataService;

    private Part _part;

    public Part MyPart
    {
        get { return _part; }
        set { this.RaiseAndSetIfChanged(ref _part, value); }
    }

    public MainViewModel(IDataService dataService)
    {
        _dataService = dataService;

        this.WhenActivated(disposables =>
        {
            _dataService.GetPart("9176900515")
                .ToObservable()
                .Subscribe(
                    result => { MyPart = result; },
                    exception => { LogMe.Log<string>(exception.Message); }
                )
                .DisposeWith(disposables);
        });
    }

    private readonly ViewModelActivator activator = new ViewModelActivator();
    ViewModelActivator ISupportsActivation.Activator
    {
        get { return activator; }
    }

}

2 个答案:

答案 0 :(得分:1)

要使WhenActivated在视图模型中工作,视图模型必须是实现ViewModel的视图的IViewFor<MainViewModel>

MainViewModel&#39; WhenActivated将由视图WhenActvated调用。

<强>更新

这是在WPF中完成的,但它在所有平台(WPF,UWP,Xamarin)上都受支持。

视图实现IViewFor<TViewModel>。根据最佳做法,ViewModel属性为DependencyProperty(或Xam.Forms中的BindableProperty)。

public partial class MainWindow : Window, IViewFor<MainViewModel>
{
    public MainWindow()
    {
        InitializeComponent();

        this.WhenActivated(d =>
        {
        // This will be called
    });
    }

    public MainViewModel ViewModel
    {
        get => (MainViewModel)GetValue(ViewModelProperty);
        set => SetValue(ViewModelProperty, value);
    }
    public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(MainViewModel), typeof(MainWindow), new PropertyMetadata(null));

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

现在,在视图中调用WhenActivated时,将调用VM中的WhenActivated

class MainViewModel : ReactiveObject, ISupportsActivation
{
    public ViewModelActivator Activator => _activator;
    private ViewModelActivator _activator = new ViewModelActivator();

    public MainViewModel()
    {
        this.WhenActivated(d =>
        {
            // This will be called
        });
    }
}

答案 1 :(得分:0)

实施ViewModel

其中一个是WhenActivated模式的描述:https://reactiveui.net/docs/handbook/when-activated/

  

WhenActivated是一种跟踪一次性用品的方法。除此之外,它还可以用于推迟ViewModel的设置,直到真正需要它为止。 WhenActivated还使我们能够开始或停止对可观察到的热点做出反应,例如定期对网络端点执行ping操作或可观察到的更新用户当前位置的后台任务。此外,当WhenActivated登台时,人们可以使用ViewModel来触发启动逻辑。

这部分模式似乎已经在问题中正确解决了。

实现视图

要激活您的ViewModel,您必须完全遵循https://reactiveui.net/docs/getting-started/#create-views中提供的特定模式

以下是关键区域:

public partial class MainWindow : IViewFor<AppViewModel>
{
    // Using a DependencyProperty as the backing store for ViewModel.
    // This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ViewModelProperty =
        DependencyProperty.Register("ViewModel",
            typeof(AppViewModel), typeof(MainWindow),
            new PropertyMetadata(null));

    public MainWindow()
    {
        InitializeComponent();
        ViewModel = new AppViewModel();

    // ....
    }

    // ....

    // Our main view model instance.
    public AppViewModel ViewModel
    {
        get => (AppViewModel)GetValue(ViewModelProperty);
        set => SetValue(ViewModelProperty, value);
    }

    // This is required by the interface IViewFor, you always just set it to use the
    // main ViewModel property. Note on XAML based platforms we have a control called
    // ReactiveUserControl that abstracts this.
    object IViewFor.ViewModel
    {
        get => ViewModel;
        set => ViewModel = (AppViewModel)value;
    }
}

请注意,当调用MainWindow设置器时,框架会注意到从该特定AppViewModel实例到该特定ViewModel实例的链接:

ViewModel = new AppViewModel();