Я использую ReactiveUI и сторонние разработчики для отображения изображений с возможностью отмены / повтора. У меня есть модель представления с командой для изменения выбранного изображения, и я хотел бы выполнить следующие действия, когда я нажимаю на кнопку отмены:
- Найти изображение, на котором произойдет следующее действие отмены
- Позвоните моей команде, чтобы изменить выбранное изображение
- Дождитесь появления наблюдаемой, реагирующей на выбранное изображение, чтобы перезагрузить аннотации на изображении
- Выполнить действие отмены изображения
У меня есть нечто, похожее на
ViewModels:
public class MyViewModel : ReactiveObject
{
public MyViewModel()
{
SelectImage = ReactiveCommand.Create<ImageViewModel, ImageViewModel>(phase => /* some code */);
_selectedImage = SelectImage.ToProperty(this, x => x.SelectedImage, someDefaultValue);
}
private readonly ObservableAsPropertyHelper<ImageViewModel> _selectedImage ;
public ImageViewModelSelectedImage=> _selectedImage.Value;
public ReactiveCommand<ImageViewModel, ImageViewModel> SelectImage { get; }
}
public class ImageViewModel
{
private object? _annot1;
public object? Annotation1
{
get => _annot1;
set => this.RaiseAndSetIfChanged(ref _annot1, value);
}
private object? _annot2;
public object? Annotation2
{
get => _annot2;
set => this.RaiseAndSetIfChanged(ref _annot2, value);
}
}
Просмотр ctor:
var onAnnotationsLoaded = ViewModel.WhenAnyValue(x => x.SelectedImage.Annotation1, x => x.SelectedImage.Annotation2, (x, y) => Unit.Default)
.Skip(1)
.Throttle(TimeSpan.FromMilliseconds(100))
.Select(_ => Observable.Start(() => LoadAnnotations(), RxApp.MainThreadScheduler));
onAnnotationsLoaded
.Subscribe(_ => { })
.DisposeWith(disposables);
UndoButton.Events()
.Click
.Select(_ => FindImageToSelect())
.Select(image => ViewModel.SelectImage.Execute(image))
.Switch()
.Select(_ => onAnnotationsLoaded);
.Select(x => x) // breakpoint here is called
.Switch()
.Select(x => x) // breakpoint here is called only the 2nd time undo button is clicked
.Subscribe(_ => /* do the undo action */);
Я пытался заменить Observable.Start
с другими методами, но на самом деле ни один из них не работает так, как мне хотелось бы.
Я почти уверен, что где-то в моей трубке или в ментальной модели наблюдаемых объектов что-то совершенно не так, но я не могу выяснить, что .