如何在ReactiveUI中仅当Deleted属性从false变为true时触发SearchResults更新
Got it, let's fix this issue. The problem right now is that any change to SelectedItem.Deleted—including switching to a non-deleted item—triggers an unwanted refresh. We need to split our trigger sources into two parts: one for any SearchTerm change (keeping your original behavior), and another that only fires when Deleted transitions specifically from false to true.
Here's how to adjust your code:
// 1. Stream for any SearchTerm changes (preserves original behavior) var searchTermUpdates = this.WhenAnyValue(x => x.SearchTerm); // 2. Stream that only triggers when SelectedItem.Deleted goes from false → true var deletedStateTransition = this.WhenAnyValue(x => x.SelectedItem) // Guard against null SelectedItem to avoid null reference exceptions .Where(selectedItem => selectedItem != null) // Switch to listening to the Deleted property of the currently selected item .Select(selectedItem => selectedItem.WhenAnyValue(x => x.Deleted)) .Switch() // Track the previous and current value of Deleted .PairWithPrevious() // Only keep the cases where we went from false to true .Where(transition => !transition.Previous && transition.Current); // Merge both streams: trigger search on SearchTerm change OR valid Deleted transition _searchResults = searchTermUpdates .Merge(deletedStateTransition.Select(_ => this.SearchTerm)) .Select(searchTerm => SearchProjects(searchTerm)) .ObserveOn(RxApp.MainThreadScheduler) .ToProperty(this, x => x.SearchResults);
Breakdown of the changes:
- searchTermUpdates: This keeps your original logic intact—any change to
SearchTermwill immediately trigger a refresh ofSearchResults. - deletedStateTransition:
- We first filter out
nullSelectedItemto prevent crashes when no item is selected. Switch()ensures we're always listening to theDeletedproperty of the currently selected item (not old, unselected items).PairWithPrevious()is a ReactiveUI extension that captures both the previous and current value ofDeleted. We use this to strictly filter for thefalse → truetransition you care about.
- We first filter out
- Merging the streams: When the valid
Deletedtransition happens, we grab the currentSearchTerm(since it hasn't changed) and pass it toSearchProjects, just like we do whenSearchTermupdates.
If you don't have access to PairWithPrevious():
If for some reason you can't use that extension, you can replicate its behavior with Scan:
.Select(deleted => new { Current = deleted, Previous = (bool?)null }) .Scan((lastState, newState) => new { Current = newState.Current, Previous = lastState.Current }) .Where(state => state.Previous == false && state.Current == true)
This works exactly the same way, tracking the previous value of Deleted to filter only the transition you want.
Now, switching to a non-deleted item won't trigger an unwanted refresh—only when you mark an item as deleted (set Deleted from false to true) or change the SearchTerm will SearchResults update.
内容的提问来源于stack exchange,提问作者Hanabi

