public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISchedulerProvider schedulerProvider) { //TODO: options for colour var swatches = new SwatchesProvider().Swatches; ReadOnlyObservableCollection<SearchOptionsProxy> data; var userOptions = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => new SearchOptionsProxy(meta, swatches,m => metadataCollection.Remove(m.SearchText))) .SubscribeMany(so => { //when a value changes, write the original value back to the cache return so.WhenAnyPropertyChanged() .Subscribe(_ => metadataCollection.Add(new SearchMetadata(so.Text, so.Filter, so.Highlight))); }) .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy=>proxy.Text)) .ObserveOn(schedulerProvider.MainThread) .Bind(out data) .Subscribe(); Data = data; AddSearchCommand = new Command(() => { metadataCollection.Add(new SearchMetadata(SearchText,false,true)); SearchText = string.Empty; }, () => SearchText.IsLongerThanOrEqualTo(3) && !metadataCollection.Metadata.Lookup((CaseInsensitiveString)SearchText).HasValue); var commandRefresher = this.WhenValueChanged(vm => vm.SearchText) .Subscribe(_ => ((Command) AddSearchCommand).Refresh()); //User feedback to guide them whilst typing SearchHint = this.WhenValueChanged(vm => vm.SearchText) .Select(text => { if (string.IsNullOrEmpty(text)) return "Type to highlight"; return text.Length < 3 ? "Enter at least 3 characters" : "Hit enter for more options"; }).ForBinding(); _cleanUp = new CompositeDisposable(commandRefresher, userOptions, SearchHint); }
public void Remove(string searchText) { var item = Searches.Lookup(searchText); if (!item.HasValue) { return; } if (!item.Value.IsGlobal) { _localMetadataCollection.Remove(searchText); } else { _combinedSearchMetadataCollection.Global.Remove(searchText); } }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISchedulerProvider schedulerProvider, SearchHints searchHints) { SearchHints = searchHints; //TODO: options for colour var swatches = new SwatchesProvider().Swatches; ReadOnlyObservableCollection<SearchOptionsProxy> data; var userOptions = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => new SearchOptionsProxy(meta, swatches,m => metadataCollection.Remove(m.SearchText))) .SubscribeMany(so => { //when a value changes, write the original value back to the cache return so.WhenAnyPropertyChanged() .Subscribe(_ => metadataCollection.Add(new SearchMetadata(so.Text, so.Filter, so.Highlight,so.UseRegex,so.IgnoreCase))); }) .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy=>proxy.Text)) .ObserveOn(schedulerProvider.MainThread) .Bind(out data) .Subscribe(); Data = data; //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe(request => { metadataCollection.Add(new SearchMetadata(request.Text, false, true, request.UseRegEx, true)); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISchedulerProvider schedulerProvider, SearchHints searchHints) { SearchHints = searchHints; //TODO: options for colour var swatches = new SwatchesProvider().Swatches; bool binding = false; var orderChanged = Observable.FromEventPattern<OrderChangedEventArgs>( h => PositionMonitor.OrderChanged += h, h => PositionMonitor.OrderChanged -= h) .Select(evt => evt.EventArgs) .Where(args=>args.PreviousOrder!=null && args.NewOrder.Length == args.PreviousOrder.Length) .Select(positionChangedArgs => { //reprioritise filters and highlights return positionChangedArgs.NewOrder .OfType<SearchOptionsProxy>() .Select((item, index) => new {Meta=(SearchMetadata)item, index}) //.Where(x => x.index != x.Meta.Position) .Select(x => new SearchMetadata(x.Meta, x.index)) .ToArray(); }) .Subscribe(positionChangedArgs => { positionChangedArgs.ForEach(metadataCollection.AddorUpdate); }); ReadOnlyObservableCollection<SearchOptionsProxy> data; var userOptions = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => new SearchOptionsProxy(meta, swatches, m => metadataCollection.Remove(m.SearchText))) .SubscribeMany(so => { //when a value changes, write the original value back to the cache return so.WhenAnyPropertyChanged() .Subscribe(_ =>metadataCollection.AddorUpdate(new SearchMetadata(metadataCollection.Metadata.Count, so.Text, so.Filter, so.Highlight, so.UseRegex, so.IgnoreCase))); }) .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) .Bind(out data) .Subscribe(); Data = data; //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe(request => { schedulerProvider.Background.Schedule(() => { metadataCollection.AddorUpdate(new SearchMetadata(metadataCollection.NextIndex(), request.Text, false, true, request.UseRegEx, true)); }); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, orderChanged); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, SearchHints searchHints) { SearchHints = searchHints; var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return(new SearchOptionsProxy(meta, colourProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, Id)); }) .SubscribeMany(so => { //when a value changes, write the original value back to the cache return(so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata)so) .Subscribe(metadataCollection.AddorUpdate)); }) .AsObservableCache(); var monitor = MonitorPositionalChanges() .Subscribe(positionChangedArgs => { positionChangedArgs.ForEach(metadataCollection.AddorUpdate); }); //load data onto grid var collection = new ObservableCollectionExtended <SearchOptionsProxy>(); var userOptions = proxyItems.Connect() .Sort(SortExpressionComparer <SearchOptionsProxy> .Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor <SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); Data = new ReadOnlyObservableCollection <SearchOptionsProxy>(collection); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe(request => { schedulerProvider.Background.Schedule(() => { var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, metadataCollection.NextIndex(), false); metadataCollection.AddorUpdate(meta); }); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, monitor, SearchHints); }
public SearchProxyCollection(ISearchMetadataCollection metadataCollection, Guid id, Action<SearchMetadata> changeScopeAction, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, ITextAssociationCollection textAssociationCollection, IThemeProvider themeProvider) { var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return new SearchOptionsProxy(meta, changeScopeAction, colourProvider, themeProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, id); }) .SubscribeMany(so => { //when a value changes, write the original value back to the metadata collection var anyPropertyHasChanged = so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata) so) .Subscribe(metadataCollection.AddorUpdate); //when an icon or colour has changed we need to record user choice so //the same choice can be used again var iconChanged = so.WhenValueChanged(proxy => proxy.IconKind, false).ToUnit(); var colourChanged = so.WhenValueChanged(proxy => proxy.HighlightHue, false).ToUnit(); var ignoreCaseChanged = so.WhenValueChanged(proxy => proxy.CaseSensitive, false).ToUnit(); var textAssociationChanged = iconChanged.Merge(colourChanged).Merge(ignoreCaseChanged) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(_ => new TextAssociation(so.Text, so.CaseSensitive, so.UseRegex, so.HighlightHue.Swatch, so.IconKind.ToString(), so.HighlightHue.Name, DateTime.UtcNow)) .Subscribe(textAssociationCollection.MarkAsChanged); return new CompositeDisposable(anyPropertyHasChanged, textAssociationChanged); }) .AsObservableCache(); Count = proxyItems.CountChanged.StartWith(0).ForBinding(); var monitor = MonitorPositionalChanges().Subscribe(metadataCollection.Add); //load data onto grid var collection = new ObservableCollectionExtended<SearchOptionsProxy>(); var includedLoader = proxyItems .Connect(proxy => !proxy.IsExclusion) .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor<SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); ReadOnlyObservableCollection<SearchOptionsProxy> excluded; var excludedLoader = proxyItems .Connect(proxy => proxy.IsExclusion) .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy => proxy.Text)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(out excluded) .DisposeMany() .Subscribe(); Excluded = excluded; Included = new ReadOnlyObservableCollection<SearchOptionsProxy>(collection); _cleanUp = new CompositeDisposable(proxyItems, includedLoader, excludedLoader, monitor); }
public SearchProxyCollection(ISearchMetadataCollection metadataCollection, Guid id, Action<SearchMetadata> changeScopeAction, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, ITextAssociationCollection textAssociationCollection, IThemeProvider themeProvider) { var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return new SearchOptionsProxy(meta, changeScopeAction, colourProvider, themeProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, id); }) .SubscribeMany(so => { //when a value changes, write the original value back to the metadata collection var anyPropertyHasChanged = so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata) so) .Subscribe(metadataCollection.AddorUpdate); //when an icon or colour has changed we need to record user choice so //the same choice can be used again var iconChanged = so.WhenValueChanged(proxy => proxy.IconKind, false).ToUnit(); var colourChanged = so.WhenValueChanged(proxy => proxy.HighlightHue, false).ToUnit(); var ignoreCaseChanged = so.WhenValueChanged(proxy => proxy.CaseSensitive, false).ToUnit(); var textAssociationChanged = iconChanged.Merge(colourChanged).Merge(ignoreCaseChanged) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(_ => new TextAssociation(so.Text, so.CaseSensitive, so.UseRegex, so.HighlightHue.Swatch, so.IconKind.ToString(), so.HighlightHue.Name, DateTime.UtcNow)) .Subscribe(textAssociationCollection.MarkAsChanged); return new CompositeDisposable(anyPropertyHasChanged, textAssociationChanged); }) .AsObservableCache(); Count = proxyItems.CountChanged.StartWith(0).ForBinding(); var monitor = MonitorPositionalChanges().Subscribe(metadataCollection.Add); //load data onto grid var collection = new ObservableCollectionExtended<SearchOptionsProxy>(); var includedLoader = proxyItems .Connect(proxy => !proxy.IsExclusion) .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor<SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); var excludedLoader = proxyItems .Connect(proxy => proxy.IsExclusion) .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy => proxy.Text)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(out var excluded) .DisposeMany() .Subscribe(); Excluded = excluded; Included = new ReadOnlyObservableCollection<SearchOptionsProxy>(collection); _cleanUp = new CompositeDisposable(proxyItems, includedLoader, excludedLoader, monitor); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, ITextAssociationCollection textAssociationCollection, SearchHints searchHints) { SearchHints = searchHints; var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return(new SearchOptionsProxy(meta, colourProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, Id)); }) .SubscribeMany(so => { //when a value changes, write the original value back to the metadata collection var anyPropertyHasChanged = so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata)so) .Subscribe(metadataCollection.AddorUpdate); //when an icon or colour has changed we need to record user choice so //the same choice can be used again var iconChanged = so.WhenValueChanged(proxy => proxy.IconKind, false).ToUnit(); var colourChanged = so.WhenValueChanged(proxy => proxy.HighlightHue, false).ToUnit(); var ignoreCaseChanged = so.WhenValueChanged(proxy => proxy.IgnoreCase, false).ToUnit(); var textAssociationChanged = iconChanged.Merge(colourChanged).Merge(ignoreCaseChanged) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(_ => new TextAssociation(so.Text, so.IgnoreCase, so.UseRegex, so.HighlightHue.Swatch, so.IconKind.ToString(), so.HighlightHue.Name, DateTime.Now)) .Subscribe(textAssociationCollection.MarkAsChanged); return(new CompositeDisposable(anyPropertyHasChanged, textAssociationChanged)); }) .AsObservableCache(); var monitor = MonitorPositionalChanges() .Subscribe(metadataCollection.Add); //load data onto grid var collection = new ObservableCollectionExtended <SearchOptionsProxy>(); var userOptions = proxyItems.Connect() .Sort(SortExpressionComparer <SearchOptionsProxy> .Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor <SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); Data = new ReadOnlyObservableCollection <SearchOptionsProxy>(collection); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested .ObserveOn(schedulerProvider.Background) .Subscribe(request => { var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, metadataCollection.NextIndex(), false); metadataCollection.AddorUpdate(meta); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, monitor, SearchHints); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISchedulerProvider schedulerProvider, SearchHints searchHints) { SearchHints = searchHints; //TODO: options for colour var swatches = new SwatchesProvider().Swatches; bool binding = false; var orderChanged = Observable.FromEventPattern <OrderChangedEventArgs>( h => PositionMonitor.OrderChanged += h, h => PositionMonitor.OrderChanged -= h) .Throttle(TimeSpan.FromMilliseconds(125)) .Select(evt => evt.EventArgs) .Where(args => args.PreviousOrder != null && args.NewOrder.Length == args.PreviousOrder.Length) .Select(positionChangedArgs => { //reprioritise filters and highlights return(positionChangedArgs.NewOrder .OfType <SearchOptionsProxy>() .Select((item, index) => new { Meta = (SearchMetadata)item, index }) //.Where(x => x.index != x.Meta.Position) .Select(x => new SearchMetadata(x.Meta, x.index)) .ToArray()); }) .Subscribe(positionChangedArgs => { positionChangedArgs.ForEach(metadataCollection.AddorUpdate); }); ReadOnlyObservableCollection <SearchOptionsProxy> data; var userOptions = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => new SearchOptionsProxy(meta, swatches, m => metadataCollection.Remove(m.SearchText))) .SubscribeMany(so => { //when a value changes, write the original value back to the cache return(so.WhenAnyPropertyChanged() .Select(_ => new SearchMetadata(so.Position, so.Text, so.Filter, so.Highlight, so.UseRegex, so.IgnoreCase)) .Subscribe(metadataCollection.AddorUpdate)); }) .Sort(SortExpressionComparer <SearchOptionsProxy> .Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) .Bind(out data) .Subscribe(); Data = data; //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested.Subscribe(request => { schedulerProvider.Background.Schedule(() => { metadataCollection.AddorUpdate(new SearchMetadata(metadataCollection.NextIndex(), request.Text, false, true, request.UseRegEx, true)); }); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, orderChanged); }
public void Remove(string searchText) { _metadataCollection.Remove(searchText); }
public SearchOptionsViewModel(ISearchMetadataCollection metadataCollection, ISearchMetadataFactory searchMetadataFactory, ISchedulerProvider schedulerProvider, IColourProvider colourProvider, IIconProvider iconsProvider, ITextAssociationCollection textAssociationCollection, SearchHints searchHints, IThemeProvider themeProvider) { SearchHints = searchHints; var proxyItems = metadataCollection.Metadata.Connect() .WhereReasonsAre(ChangeReason.Add, ChangeReason.Remove) //ignore updates because we update from here .Transform(meta => { return new SearchOptionsProxy(meta, colourProvider, themeProvider, new IconSelector(iconsProvider, schedulerProvider), m => metadataCollection.Remove(m.SearchText), iconsProvider.DefaultIconSelector, Id); }) .SubscribeMany(so => { //when a value changes, write the original value back to the metadata collection var anyPropertyHasChanged = so.WhenAnyPropertyChanged() .Select(_ => (SearchMetadata) so) .Subscribe(metadataCollection.AddorUpdate); //when an icon or colour has changed we need to record user choice so //the same choice can be used again var iconChanged = so.WhenValueChanged(proxy => proxy.IconKind,false).ToUnit(); var colourChanged = so.WhenValueChanged(proxy => proxy.HighlightHue, false).ToUnit(); var ignoreCaseChanged = so.WhenValueChanged(proxy => proxy.IgnoreCase, false).ToUnit(); var textAssociationChanged = iconChanged.Merge(colourChanged).Merge(ignoreCaseChanged) .Throttle(TimeSpan.FromMilliseconds(250)) .Select(_=> new TextAssociation(so.Text, so.IgnoreCase, so.UseRegex, so.HighlightHue.Swatch, so.IconKind.ToString(), so.HighlightHue.Name, DateTime.Now)) .Subscribe(textAssociationCollection.MarkAsChanged); return new CompositeDisposable(anyPropertyHasChanged, textAssociationChanged); }) .AsObservableCache(); var monitor = MonitorPositionalChanges() .Subscribe(metadataCollection.Add); //load data onto grid var collection = new ObservableCollectionExtended<SearchOptionsProxy>(); var userOptions = proxyItems.Connect() .Sort(SortExpressionComparer<SearchOptionsProxy>.Ascending(proxy => proxy.Position)) .ObserveOn(schedulerProvider.MainThread) //force reset for each new or removed item dues to a bug in the underlying dragablz control which inserts in an incorrect position .Bind(collection, new ObservableCollectionAdaptor<SearchOptionsProxy, string>(0)) .DisposeMany() .Subscribe(); Data = new ReadOnlyObservableCollection<SearchOptionsProxy>(collection); //command to add the current search to the tail collection var searchInvoker = SearchHints.SearchRequested .ObserveOn(schedulerProvider.Background) .Subscribe(request => { var meta = searchMetadataFactory.Create(request.Text, request.UseRegEx, metadataCollection.NextIndex(), false); metadataCollection.AddorUpdate(meta); }); _cleanUp = new CompositeDisposable(searchInvoker, userOptions, searchInvoker, monitor, SearchHints); }