ReactiveUI - 多个InvokeCommand不适用于单个可观察的

时间:2016-08-24 19:07:27

标签: vb.net winforms reactiveui

我的DetailsViewModel监视所选EnvelopeViewModel中的更改并更新DetailsViewModel的AgendaItemId。

MessageBus.Current.Listen(Of EnvelopeViewModel) _
        .Where(Function(x) x IsNot Nothing) _
        .Select(Function(x) x.AgendaItemID) _
        .ToPropertyEx(Me, Function(vm) vm.AgendaItemId)

我使用_agendaItemService返回的AgendaItem更新DetailsViewModel。我相信这会引发问题。

UpdateViewModel = ReactiveCommand.CreateAsyncTask(Function(x) _agendaItemService.FindAsync(AgendaItemId))
UpdateViewModel.SubscribeOn(RxApp.MainThreadScheduler).Subscribe(Sub(agendaItem) UpdateDetails(agendaItem))
UpdateViewModel.ThrownExceptions.Subscribe(Sub(ex) Log.ErrorException("LoadViewModel", ex))

WhenAnyValue(Function(vm) vm.AgendaItemId) _
  .Where(Function(agendaItemId) agendaItemId > 0) _
  .InvokeCommand(UpdateViewModel)

Private Sub UpdateDetails(agendaItem As AgendaItem)

    _agendaItem = agendaItem

    PrimaryAgendaCategoryId = _agendaItem.AgendaCategory.ParentId

    PrimaryAmount = agendaItem.Amounts.Where(Function(x) x.AmountType = AmountType.Primary).Sum(Function(x) x.Value)
    SecondaryAmount = agendaItem.Amounts.Where(Function(x) x.AmountType = AmountType.Secondary).Sum(Function(x) x.Value)
    LocalMatchAmount = agendaItem.Amounts.Where(Function(x) x.AmountType = AmountType.LocalMatch).Sum(Function(x) x.Value)
    ChangeOrderTotalAmount = agendaItem.Amounts.Where(Function(x) x.AmountType = AmountType.ChangeOrder).Sum(Function(x) x.Value)
    ProjectTotalAmount = agendaItem.Amounts.Sum(Function(x) x.Value)

    Mapper.Map(_agendaItem, Me)

    'TODO fix this attempt at getting save button to refresh when amounts are changed and saved.
    Name = ""
    Name = _agendaItem.Name

End Sub

这实际上似乎有效。 DetailsView将使用新值进行更新。事情失败的地方是我尝试更新DepartmentContacts。

GetDepartmentContacts = ReactiveCommand.CreateAsyncTask(Function(x) _departmentService.GetDepartmentContactsAsync(AgendaItemId))
GetDepartmentContacts.ToPropertyEx(Me, Function(x) x.DepartmentContacts, New BindingList(Of PersonContactViewModel))
GetDepartmentContacts.ThrownExceptions.Subscribe(Sub(ex) Log.ErrorException("GetDepartmentContacts", ex))

WhenAnyValue(Function(vm) vm.AgendaItemId) _
        .Where(Function(id) id > 0) _
        .InvokeCommand(GetDepartmentContacts)

ObservableAsPropertyHelper DepartmentContacts无法更新视图。

但是,如果我注释掉UpdateViewModel命令的调用,则会更新DepartmentContacts而不会出现问题。

ReactiveUI中必须有更好的方法来更新我的ViewModel。

1 个答案:

答案 0 :(得分:0)

我相信我找到了Combining Commands的答案。

我认为问题是我无法在同一个观察者身上使用InvokeCommand两次。 ReactiveCommand.CreateCombined让我将这两个命令合并为一个可以调用的命令,它将处理调用分配给它的两个命令。

UpdateViewModel = ReactiveCommand.CreateAsyncTask(Function(x) _agendaItemService.FindAsync(AgendaItemId))
UpdateViewModel.SubscribeOn(RxApp.MainThreadScheduler).Subscribe(Sub(agendaItem) UpdateDetails(agendaItem))
UpdateViewModel.ThrownExceptions.Subscribe(Sub(ex) Log.ErrorException("LoadViewModel", ex))

GetDepartmentContacts = ReactiveCommand.CreateAsyncTask(Function(x) _departmentService.GetDepartmentContactsAsync(AgendaItemId))
GetDepartmentContacts.ToPropertyEx(Me, Function(x) x.DepartmentContacts, New BindingList(Of PersonContactViewModel))
GetDepartmentContacts.ThrownExceptions.Subscribe(Sub(ex) Log.ErrorException("GetDepartmentContacts", ex))

RefreshAgendaItemValues = ReactiveCommand.CreateCombined(RefreshViewModel, RefreshDepartmentContacts)

WhenAnyValue(Function(vm) vm.AgendaItemId) _
    .Where(Function(id) id > 0) _
    .InvokeCommand(RefreshAgendaItemValues)