public SelectedToolViewModel(UIView toolboxView, AvailableToolsContainerViewController container, MeetingViewModel meeting, IReactiveList<IToolViewModel> selectedTools, NavigationPaneViewModel navigationPane) { SelectedTools = selectedTools; IsEmpty = SelectedTools.Count == 0; SelectedTools.Changed.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(p => { IsEmpty = SelectedTools.Count == 0; }); var showAvailableToolsCommand = new ReactiveCommand(); showAvailableToolsCommand.ObserveOn(RxApp.MainThreadScheduler).Subscribe(_ => { UIView.BeginAnimations(null); UIView.SetAnimationDuration(0.25); toolboxView.Alpha = 1.0f; UIView.CommitAnimations(); }); container.CloseToolboxRequested += (s, e) => { UIView.BeginAnimations(null); UIView.SetAnimationDuration(0.25); toolboxView.Alpha = 0.0f; UIView.CommitAnimations(); }; ShowAvailableToolsCommand = showAvailableToolsCommand; navigationPane.ShowToolLibraryAction = () => ShowAvailableToolsCommand.Execute(null); var setActiveToolsCommand = new ReactiveCommand(); setActiveToolsCommand.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(tool => meeting.ActiveTool = (IToolViewModel)tool); SetActiveToolCommand = setActiveToolsCommand; }
protected BaseMenuViewModel(IAccountsService accountsService) { AccountsService = accountsService; DeletePinnedRepositoryCommand = ReactiveCommand.Create(); PinnedRepositories = new ReactiveList<PinnedRepository>(AccountsService.ActiveAccount.PinnnedRepositories); DeletePinnedRepositoryCommand.OfType<PinnedRepository>() .Subscribe(x => { AccountsService.ActiveAccount.PinnnedRepositories.Remove(x); AccountsService.Update(AccountsService.ActiveAccount); PinnedRepositories.Remove(x); }); }
public MainViewModel() { this.dinosaurs = new ReactiveList <string>( Data .Dinosaurs .All .Select(dinosaur => dinosaur.Name) .ToList()); this.confirmDeleteDinosaur = new Interaction <UndoViewModel, bool>(); this.outstandingUndoInteraction = new SerialDisposable(); var canAdd = this .WhenAnyValue(x => x.Name) .Select(name => !string.IsNullOrWhiteSpace(name)); this.addDinosaurCommand = ReactiveCommand.CreateFromObservable( () => Observable .Return(Unit.Default) .Delay(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .Do(_ => this.dinosaurs.Add(this.Name)), canAdd); var canDelete = this .WhenAnyValue(x => x.SelectedDinosaur) .Select(selectedDinosaur => selectedDinosaur != null); this.deleteDinosaurCommand = ReactiveCommand.Create( () => { var index = this.dinosaurs.IndexOf(this.SelectedDinosaur); var dinosaurName = this.dinosaurs[index]; this.dinosaurs.RemoveAt(index); var undoInfo = new UndoViewModel(dinosaurName); this.outstandingUndoInteraction.Disposable = this .confirmDeleteDinosaur .Handle(undoInfo) .Where(answer => !answer) .Do(_ => this.dinosaurs.Insert(index, dinosaurName)) .Subscribe(); }, canDelete); }
public static CompositeDisposable KeepCollectionInSyncOfType <T, T2>(this IReactiveList <T> list, IList <T2> destination, Func <T, bool> filter = null) where T : class, T2 where T2 : class { if (list == null) { throw new ArgumentNullException(nameof(list)); } if (destination == null) { throw new ArgumentNullException(nameof(destination)); } lock (list) { list.SyncCollectionOfTypeLocked(destination, filter); return(list.TrackChangesOfType(destination.Add, x => destination.Remove(x), reset => reset.SyncCollectionOfTypeLocked(destination), filter)); } }
public static CompositeDisposable TrackChangesOfType <T, T2>(this IReactiveList <T2> list, Action <T2> add, Action <T2> remove, Action <IEnumerable <T2> > reset, Func <T, bool> filter = null) where T2 : class where T : class, T2 { if (list == null) { throw new ArgumentNullException(nameof(list)); } var disposables = new CompositeDisposable(); if (add != null) { var o = list.ItemsAdded.OfType <T>(); if (filter != null) { o = o.Where(filter); } disposables.Add(o.Subscribe(add)); } if (remove != null) { var o = list.ItemsRemoved.OfType <T>(); if (filter != null) { o = o.Where(filter); } disposables.Add(o.Subscribe(remove)); } if (reset != null) { disposables.Add(list.ShouldReset .Subscribe( x => reset(filter == null ? list.OfType <T>().ToArray() : list.OfType <T>().Where(filter).ToArray()))); } return(disposables); }
/// <summary> /// Constructor when instantiating self-saving object /// </summary> /// <param name="path">Path to save</param> /// <param name="marshallManager">Marshaller dependency</param> public SystemMapping(string path, IMarshallManager marshallManager) { Mappings = new ReactiveList <Mapping> { ChangeTrackingEnabled = true }; Observable.Merge( Mappings.ItemChanged.Select(x => Unit.Default), Mappings.ItemsAdded.Select(x => Unit.Default), Mappings.ItemsRemoved.Select(x => Unit.Default) ).Sample(TimeSpan.FromSeconds(1)).Subscribe(x => Save(path, marshallManager)); // if mapping goes stale, remove it. Mappings.ItemChanged.Subscribe(e => { var mapping = e.Sender; if (mapping.IsStale) { Mappings.Remove(mapping); } }); }
/// <summary> /// Takes each list produced by this observable and mirrors its contents in the target list. /// The target list is modified, not replaced. /// The type of the target list property is IReadOnlyReactiveList because it doesn't make sense to have a mutible list /// if this binding keeps changing the contents of the list, but the type of the actual object should be ReactiveList /// so the list can be modified by this binding. /// </summary> /// <typeparam name="TObj">The type of viewmodel</typeparam> /// <typeparam name="TListItem">The type of object contained in the list</typeparam> /// <param name="data">The observable to take lists from.</param> /// <param name="target">The viewmodel that is used as a base for finding the target list property</param> /// <param name="property">The IReactiveList property that will be modified.</param> /// <returns>A disposable to break the binding</returns> public static IDisposable BindListContents <TObj, TListItem>(this IObservable <IList <TListItem> > data, TObj target, Expression <Func <TObj, IReadOnlyReactiveList <TListItem> > > property) { IObservable <IReadOnlyReactiveList <TListItem> > targetListObservable = target.WhenAnyValue(property); return(Observable.CombineLatest(targetListObservable, data, (a, b) => (TargetList: a, SourceList: b)).Subscribe(t => { IReactiveList <TListItem> latestTargetList = t.TargetList as IReactiveList <TListItem>; IList <TListItem> latestData = t.SourceList; if (latestTargetList == null) { return; } if (latestData == null) { latestTargetList.Clear(); return; } var changes = LongestCommonSubsequence.GetChanges(latestTargetList, latestData).ToArray(); if (changes.Length == 0) { return; } using (changes.Length > 1 ? latestTargetList.SuppressChangeNotifications() : Disposable.Empty) { foreach ((int index, TListItem item, LongestCommonSubsequence.ChangeType changeType)change in changes) { if (change.changeType == LongestCommonSubsequence.ChangeType.Removed) { latestTargetList.RemoveAt(change.index); } else if (change.changeType == LongestCommonSubsequence.ChangeType.Added) { latestTargetList.Insert(change.index, change.item); } } } })); }
public MainViewModel() { this.dinosaurs = new ReactiveList <string>( Data .Dinosaurs .All .Select(dinosaur => dinosaur.Name) .ToList()); this.addDinosaurCommand = ReactiveCommand.CreateFromObservable( () => Observable .Return(Unit.Default) .Delay(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .Do(_ => this.dinosaurs.Add(this.Name))); this.deleteDinosaurCommand = ReactiveCommand.CreateFromObservable( () => Observable .Return(Unit.Default) .Delay(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .Do(_ => this.dinosaurs.Remove(this.SelectedDinosaur))); }
void SetupCollectionItems <T>(IReactiveList <T> src, IReactiveList <IHierarchicalLibraryItem> dst, Func <T, bool> predicate = null) where T : Collection { lock (src) { var srcF = predicate == null ? src : src.Where(predicate); lock (dst) dst.AddRange(srcF.Select(CreateCustomModSet)); _disposables.Add(src.TrackChanges( x => dst.AddLocked(CreateCustomModSet(x)), x => { lock (CollectionsGroup.Children) dst.RemoveLocked(GetCollection(x)); }, reset => { lock (dst) { lock (CollectionsGroup.Children) dst.RemoveAll(GetCollections().ToArray()); dst.AddRange(reset.Select(CreateCustomModSet)); } }, predicate)); } }
public MainViewModel() { this.dinosaurs = new ReactiveList <string>( Data .Dinosaurs .All .Select(dinosaur => dinosaur.Name) .ToList()); this.addDinosaurCommand = ReactiveCommand.CreateFromTask( async() => { await Task.Delay(TimeSpan.FromSeconds(1)); this.dinosaurs.Remove(this.SelectedDinosaur); }); this.deleteDinosaurCommand = ReactiveCommand.CreateFromTask( async() => { await Task.Delay(TimeSpan.FromSeconds(1)); this.dinosaurs.Remove(this.SelectedDinosaur); }); }
public static CompositeDisposable TrackChangesOnUiThread <T>(this IReactiveList <T> list, Action <T> add, Action <T> remove, Action <IEnumerable <T> > reset, Func <T, bool> filter = null) { if (list == null) { throw new ArgumentNullException(nameof(list)); } var disposables = new CompositeDisposable(); if (add != null) { var o = list.ItemsAdded; if (filter != null) { o = o.Where(filter); } disposables.Add(o.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(add)); } if (remove != null) { var o = list.ItemsRemoved; if (filter != null) { o = o.Where(filter); } disposables.Add(o.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(remove)); } if (reset != null) { disposables.Add(list.ShouldReset .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => reset(filter == null ? list.ToArray() : list.Where(filter).ToArray()))); } return(disposables); }
/// <summary> /// Constructor method. /// </summary> public ConsolesPanelViewModel( IAppState appState = null, IProcessFactory processFactory = null, IProcessesTracker processesTracker = null, IProcessRepository processesRepository = null, IProcessesInteropAgent consolesInteropAgent = null, ISnackbarMessageQueue snackbarMessageQueue = null) { _appState = appState ?? Locator.CurrentMutable.GetService <IAppState>(); _processFactory = processFactory ?? Locator.CurrentMutable.GetService <IProcessFactory>(); _processesTracker = processesTracker ?? Locator.CurrentMutable.GetService <IProcessesTracker>(); _processesRepository = processesRepository ?? Locator.CurrentMutable.GetService <IProcessRepository>(); _consolesInteropAgent = consolesInteropAgent ?? Locator.CurrentMutable.GetService <IProcessesInteropAgent>(); _snackbarMessageQueue = snackbarMessageQueue ?? Locator.CurrentMutable.GetService <ISnackbarMessageQueue>(); // Lists _consoleProcessEntities = new ReactiveList <ProcessEntity>() { ChangeTrackingEnabled = false }; _consolesList = _consoleProcessEntities.CreateDerivedCollection( selector: process => Mapper.Map <IProcessViewModel>(process) ); // Load Processess _loadConsolesCommand = ReactiveCommand.CreateFromTask(async() => await LoadConsolesCommandAction()); _loadConsolesCommand.IsExecuting.BindTo(this, @this => @this.IsLoadingConsoles); _loadConsolesCommand.Subscribe(entities => LoadConsolesCommandHandler(entities)); // Create Instances _startConsoleProcessCommandFactory = () => { var command = ReactiveCommand.CreateFromTask <IProcessViewModel, IProcessInstanceViewModel>(async(option) => await StartConsoleProcessCommandAction(option)); command.ThrownExceptions.Subscribe(@exception => StartConsoleProcessCommandError(@exception)); command.Subscribe(instance => StartConsoleProcessCommandHandler(instance)); return(command); }; }
/// <summary> /// Constructor method. /// </summary> public ProcessesManagerViewModel(IProcessRepository processesRepository = null, IValidator <IProcessViewModel> processViewModelaValidator = null) { _processesRepository = processesRepository ?? Locator.CurrentMutable.GetService <IProcessRepository>(); _formDataValidator = processViewModelaValidator ?? Locator.CurrentMutable.GetService <IValidator <IProcessViewModel> >(); // Lists _processesSource = new ReactiveList <ProcessEntity>() { ChangeTrackingEnabled = true }; _processesList = _processesSource.CreateDerivedCollection( selector: entity => Mapper.Map <IProcessViewModel>(entity), filter: entity => FilterEntity(entity), signalReset: this.ObservableForProperty(@this => @this.FilterText).Throttle(TimeSpan.FromMilliseconds(175), RxApp.MainThreadScheduler) ); // Add _addProcessCommand = ReactiveCommand.Create(() => AddProcessCommandAction()); // Edit this.WhenAnyValue(viewModel => viewModel.SelectedProcess) .Where(option => option != null) .Subscribe(process => EditProcessCommandAction(process)); // Save _saveProcessCommand = ReactiveCommand.Create(() => SaveProcessAction()); // Cancel _cancelFormCommand = ReactiveCommand.Create(() => CancelFormCommandAction()); // Delete _deleteProcessCommand = ReactiveCommand.Create(() => DeleteProcessCommandAction()); // Load Processess _loadProcessesCommand = ReactiveCommand.CreateFromTask(async() => await LoadProcessesCommandAction()); _loadProcessesCommand.IsExecuting.BindTo(this, @this => @this.IsLoadingProcesses); _loadProcessesCommand.Subscribe(entities => LoadProcessesCommandHandler(entities)); }
public static Task SimpleCollectionLoad <T>(this IReactiveList <T> viewModel, GitHubRequest <List <T> > request, bool?forceDataRefresh, Action <Func <Task> > assignMore = null) where T : new() { if (assignMore == null) { assignMore = (x) => {} } ; return(viewModel.RequestModel(request, forceDataRefresh, response => { viewModel.CreateMore(response, assignMore, x => { // This is f*****g broken for iOS because it can't handle estimated rows and the insertions // that ReactiveUI seems to be producing using (viewModel.SuppressChangeNotifications()) { viewModel.AddRange(x); } }); viewModel.Reset(response.Data); })); } }
public SelectedToolViewModel(UIView toolboxView, AvailableToolsContainerViewController container, MeetingViewModel meeting, IReactiveList <IToolViewModel> selectedTools, NavigationPaneViewModel navigationPane) { SelectedTools = selectedTools; IsEmpty = SelectedTools.Count == 0; SelectedTools.Changed.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(p => { IsEmpty = SelectedTools.Count == 0; }); var showAvailableToolsCommand = new ReactiveCommand(); showAvailableToolsCommand.ObserveOn(RxApp.MainThreadScheduler).Subscribe(_ => { UIView.BeginAnimations(null); UIView.SetAnimationDuration(0.25); toolboxView.Alpha = 1.0f; UIView.CommitAnimations(); }); container.CloseToolboxRequested += (s, e) => { UIView.BeginAnimations(null); UIView.SetAnimationDuration(0.25); toolboxView.Alpha = 0.0f; UIView.CommitAnimations(); }; ShowAvailableToolsCommand = showAvailableToolsCommand; navigationPane.ShowToolLibraryAction = () => ShowAvailableToolsCommand.Execute(null); var setActiveToolsCommand = new ReactiveCommand(); setActiveToolsCommand.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(tool => meeting.ActiveTool = (IToolViewModel)tool); SetActiveToolCommand = setActiveToolsCommand; }
public MainViewModel() { this.dinosaurs = new ReactiveList <string>( Data .Dinosaurs .All .Select(dinosaur => dinosaur.Name) .ToList()); this.confirmDeleteDinosaur = new Interaction <string, bool>(); var canAdd = this .WhenAnyValue(x => x.Name) .Select(name => !string.IsNullOrWhiteSpace(name)); this.addDinosaurCommand = ReactiveCommand.CreateFromObservable( () => Observable .Return(Unit.Default) .Delay(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .Do(_ => this.dinosaurs.Add(this.Name)), canAdd); var canDelete = this .WhenAnyValue(x => x.SelectedDinosaur) .Select(selectedDinosaur => selectedDinosaur != null); this.deleteDinosaurCommand = ReactiveCommand.CreateFromObservable( () => this .confirmDeleteDinosaur .Handle(this.SelectedDinosaur) .Where(result => result) .Select(_ => Unit.Default) .ObserveOn(RxApp.MainThreadScheduler) .Do(_ => this.dinosaurs.Remove(this.SelectedDinosaur)), canDelete); }
protected override async Task Load(IApplicationService applicationService, IReactiveList <Repository> repositories) { var watchers = await applicationService.Client.Repositories.GetWatched(); repositories.AddRange(watchers.Select(x => { return(new Repository { Name = x.Name, CreatedOn = x.UtcCreatedOn, Description = x.Description, FullName = x.Owner + "/" + x.Slug, UpdatedOn = x.UtcLastUpdated, Owner = new User { Username = x.Owner, Links = new User.UserLinks { Avatar = new Link(x.Logo) } } }); })); }
public MainViewModel() { this.dinosaurs = new ReactiveList <string>( Data .Dinosaurs .All .Select(dinosaur => dinosaur.Name) .ToList()); var canAdd = this .WhenAnyValue(x => x.Name) .Select(name => !string.IsNullOrWhiteSpace(name)); this.addDinosaurCommand = ReactiveCommand.Create( () => this.dinosaurs.Add(this.Name), canAdd); var canDelete = this .WhenAnyValue(x => x.SelectedDinosaur) .Select(selectedDinosaur => selectedDinosaur != null); this.deleteDinosaurCommand = ReactiveCommand.Create( () => { this.dinosaurs.Remove(this.SelectedDinosaur); }, canDelete); }
public MainViewModel() { this.activator = new ViewModelActivator(); this.dinosaurModels = new ReactiveList<Data.Dinosaur>( Data .Dinosaurs .All .Take(10)); this.dinosaurs = this .dinosaurModels .CreateDerivedCollection( selector: dinosaur => new DinosaurViewModel(dinosaur.Name)); this .WhenActivated( disposables => { Observable .Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .Do(_ => MakeRandomChange()) .Subscribe() .DisposeWith(disposables); }); }
public FeedGroupViewModel( Func <Article, FeedItemViewModel> factory, INavigationService navigationService, IFeedStoreService feedStoreService, ISettingManager settingManager, Category category) { _navigationService = navigationService; _feedStoreService = feedStoreService; _settingManager = settingManager; _category = category; _factory = factory; _source = new ReactiveList <FeedItemViewModel> { ChangeTrackingEnabled = true }; Items = _source.CreateDerivedCollection(x => x, x => !(!ShowRead && x.Read)); Modify = ReactiveCommand.CreateFromTask( () => _navigationService.Navigate <ChannelViewModel>() ); Fetch = ReactiveCommand.CreateFromTask(DoFetch); Fetch.IsExecuting.Skip(1) .Subscribe(x => IsLoading = x); Items.CountChanged .Select(count => count == 0) .Subscribe(x => IsEmpty = x); Error = new Interaction <Exception, bool>(); Fetch.ThrownExceptions .ObserveOn(RxApp.MainThreadScheduler) .SelectMany(error => Error.Handle(error)) .Where(retryRequested => retryRequested) .Select(x => Unit.Default) .InvokeCommand(Fetch); }
/// <summary> /// Default constructor when serializing. Nothing auto-saves here. /// </summary> public SystemMapping() { Mappings = new ReactiveList <Mapping>(); }
public GenericOutlineViewSource(NSOutlineView outlineView, IReactiveList <T> items, Func <T, string> groupBy, Func <T, string> iconExtractor, Func <T, string> titleExtractor) { items.Changed.Subscribe(args => ReloadItems(outlineView, items, groupBy, iconExtractor, titleExtractor)); ReloadItems(outlineView, items, groupBy, iconExtractor, titleExtractor); }
public ProfileViewModel(IApplicationService applicationService, INetworkActivityService networkActivity, IFeaturesService featuresService) { StumbleHistory = new ReactiveList <StumbledRepository>(); GoToInterestsCommand = ReactiveCommand.Create(); Username = applicationService.Account.Username; Action updateStumbled = () => { var stumbledRepositories = applicationService.Account.StumbledRepositories.Count(); Interests = applicationService.Account.Interests.Count(); Likes = applicationService.Account.StumbledRepositories.LikedRepositories(); Dislikes = applicationService.Account.StumbledRepositories.DislikedRepositories(); HasMoreHistory = stumbledRepositories > 30; if (stumbledRepositories != StumbledRepositories) { StumbledRepositories = stumbledRepositories; StumbleHistory.Reset(applicationService.Account.StumbledRepositories.Query.OrderByDescending(x => x.CreatedAt).Take(30)); } }; this.WhenActivated(d => { if (applicationService.Account != null) { updateStumbled(); d(applicationService.RepositoryAdded .Buffer(TimeSpan.FromSeconds(5)) .Where(x => x.Count > 0) .ObserveOn(SynchronizationContext.Current) .Subscribe(x => updateStumbled())); } CanPurchase = !featuresService.ProEditionEnabled; }); GoToRepositoryCommand = ReactiveCommand.Create(); GoToRepositoryCommand.OfType <StumbledRepository>().Subscribe(x => { var vm = CreateViewModel <RepositoryViewModel>(); vm.RepositoryIdentifier = new BaseRepositoryViewModel.RepositoryIdentifierModel(x.Owner, x.Name); ShowViewModel(vm); }); GoToPurchaseCommand = ReactiveCommand.Create(); GoToPurchaseCommand.Subscribe(_ => CreateAndShowViewModel <PurchaseProViewModel>()); GoToHistoryCommand = ReactiveCommand.Create(); GoToHistoryCommand.Subscribe(_ => CreateAndShowViewModel <HistoryViewModel>()); GoToLikesCommand = ReactiveCommand.Create(); GoToLikesCommand.Subscribe(_ => CreateAndShowViewModel <LikedRepositoriesViewModel>()); GoToDislikesCommand = ReactiveCommand.Create(); GoToDislikesCommand.Subscribe(_ => CreateAndShowViewModel <DislikedRepositoriesViewModel>()); GoToSettingsCommand = ReactiveCommand.Create(); GoToSettingsCommand.Subscribe(_ => CreateAndShowViewModel <SettingsViewModel>()); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { User = await applicationService.Client.User.Current(); }); LoadCommand.TriggerNetworkActivity(networkActivity); }
public MyVM(IReactiveList data) { this.data = data; this.DataCollectionView = new ListCollectionView(this.data); this.DataCollectionView.Filter = FilterData; }
public CustomMeetingListTableViewSource(UITableView tableView, IReactiveList <MeetingViewModel> meetings, NSString cellKey, float sizeHint) : base(tableView, meetings, cellKey, sizeHint) { }
public LapTimesDataSource(IReactiveList<LapTime> items) { Items = items; }
protected override Task Load(IApplicationService applicationService, IReactiveList <Repository> repositories) { return(applicationService.Client.ForAllItems(x => x.Repositories.GetForks(_username, _repository), repositories.AddRange)); }
public ChatsViewModel(IScreen hostScreen) { HostScreen = hostScreen; _chatRooms = new ReactiveList <ChatRoom>(); }
/// <summary> /// Initializes a new instance of the <see cref="ObservableCacheToReactiveListAdaptor{TObject,TKey}"/> class. /// </summary> /// <param name="target">The target.</param> /// <param name="resetThreshold">The reset threshold.</param> /// <exception cref="System.ArgumentNullException">target</exception> public ObservableCacheToReactiveListAdaptor(ReactiveList <TObject> target, int resetThreshold = 50) { _target = target ?? throw new ArgumentNullException(nameof(target)); _resetThreshold = resetThreshold; }
protected abstract Task Load(IApplicationService applicationService, IReactiveList <Repository> repositories);
public LapTimesDataSource(IReactiveList <LapTime> items) { Items = items; }
public static void ReplaceLocked <T>(this IReactiveList <T> col, IEnumerable <T> replacement) { lock (col) col.Replace(replacement); }
public static void Replace <T>(this IReactiveList <T> col, IEnumerable <T> replacement) { col.Clear(); col.AddRange(replacement); }