Я не знаю, как назвать этот вопрос, поскольку я не уверен, что не так, но у меня проблемы с наблюдением за командами в другой модели просмотра.
У меня есть BoxPageViewModel, который содержит SourceCache<BoxViewModel>
«Коробки» и SourceCache<ItemViewModel>
«Элементы». Мне нужна функциональность для добавления ItemViewModel в BoxViewModel, а затем его следует удалить из 'Items'.
Мой план состоит в том, чтобы добавить в BoxViewModel команду Add, которая добавляет элемент в SourceList в BoxViewModel . Модель BoxPageViewModel "слушает", когда какой-либо из ее блоков вызывает "Добавить", а затем удаляет самый новый элемент этого блока из "Items"
Я просмотрел документацию для шины сообщений чтобы узнать, как наблюдать, когда вызывается команда в другой модели просмотра. Я вроде как заставил его работать, но не совсем.
Моя проблема в том, что код для удаления элемента из ItemsSource вызывается только до того, как ObservableAsPropertyHelper 'IsFull' в BoxViewModel установлен для первого время, и я понятия не имею, почему. На данный момент IsFull должно быть истинным, если Box содержит 2 или более элементов. Когда я добавляю первый элемент в Box, он удаляется из элементов в BoxPageViewModel. Но когда я добавляю второй элемент, код для удаления элемента из Items никогда не вызывается.
Если я удалю «IsFull», он будет работать нормально, но мне действительно нужен способ узнать, когда все ящики «заполнены» или «закончены» каким-либо образом.
Я пробовал использовать .ToObservableChangeSet().AutoRefreshOnObservable(x => x.Add)
вместо .ToObservableChangeSet().AutoRefresh()
, но это не имеет значения. Я немного растерялся, так как не совсем понимаю, как это работает. Я действительно хотел бы получить объяснение того, почему код ведет себя именно так.
Бонусный вопрос: я также не могу получить для свойства «Done» BoxPageViewModel значение true, хотя я проверил в тестовом методе _boxes.Select(b => b.All(x => x.IsFull))
верно. Что-то не так с тем, как я определил это свойство?
public class BoxViewModel : ReactiveObject
{
readonly ObservableAsPropertyHelper<bool> isFull;
public bool IsFull => isFull.Value;
public SourceList<Item> Items = new SourceList<Item>();
public ReactiveCommand<int, Unit> Add { get; }
public BoxViewModel()
{
Add = ReactiveCommand.Create<int>(AddToBox);
Items.Connect()
.ToCollection()
.Select(c => c.Count >= 2)
.ToProperty(this, x => x.IsFull, out isFull);
}
private void AddToBox(int id)
{
// Adding a new item while testing.
Items.Add(new Item { Id = id });
}
}
В BoxPageViewModel я пытаюсь наблюдать, когда вызывается команда AddToBox, а затем удаляю элемент из его Items SourceCache.
public class BoxPageViewModel : ReactiveObject, IRoutableViewModel
{
private SourceCache<Item, int> ItemsSource = new SourceCache<Item, int>(x => x.Id);
private SourceCache<BoxViewModel, int> BoxSource = new SourceCache<BoxViewModel, int>(x => x.Id);
private ReadOnlyObservableCollection<BoxViewModel> _boxes;
public ReadOnlyObservableCollection<BoxViewModel> Boxes => _boxes;
private ReadOnlyObservableCollection<Item> _items;
public ReadOnlyObservableCollection<Item> Items => _items;
readonly ObservableAsPropertyHelper<bool> done;
public bool Done => done.Value;
public BoxPageViewModel()
{
var box1 = new BoxViewModel { Id = 1 };
var box2 = new BoxViewModel { Id = 2 };
BoxSource.AddOrUpdate(box1);
BoxSource.AddOrUpdate(box2);
// I have left out the part where my items are created
ItemsSource.AddOrUpdate(items);
ItemsSource.Connect()
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out _items)
.Subscribe();
BoxSource.Connect()
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out _boxes)
.Subscribe();
_boxes.ToObservableChangeSet()
.ToCollection()
.Select(b => b.All(x => x.IsFull))
.ToProperty(this, x => x.Done, out done);
_boxes
.ToObservableChangeSet()
.AutoRefresh()
.Select(_ => WhenAnyBoxAdded())
.Switch()
.Subscribe(box =>
{
var latestItem = box.Items.Items.Last();
ItemsSource.Remove(latestItem.Id);
});
}
IObservable<BoxViewModel> WhenAnyBoxAdded()
{
return _boxes
.Select(x => x.Add.Select(_ => x))
.Merge();
}
}