using System.Linq; using System.Reactive; using System.Reactive.Linq; using DynamicData; using ReactiveUI; namespace NodeNetwork.Toolkit.BreadcrumbBar { /// /// Viewmodel for a single element of the BreadcrumbBar. /// public class BreadcrumbViewModel : ReactiveObject { #region Name /// /// Displayed name of the crumb. /// public string Name { get => _name; set => this.RaiseAndSetIfChanged(ref _name, value); } private string _name = ""; #endregion } /// /// ViewModel for the BreadcrumbBar. /// This UI element displays a path as a list of path elements (crumbs), allowing navigation by selection of path elements. /// public class BreadcrumbBarViewModel : ReactiveObject { static BreadcrumbBarViewModel() { NNViewRegistrar.AddRegistration(() => new BreadcrumbBarView(), typeof(IViewFor)); } /// /// The path that is currently displayed in the bar. /// Add or remove elements to modify the path. /// public ISourceList ActivePath { get; } = new SourceList(); #region ActiveElement /// /// The deepest element of the currect path. (Last element of ActivePath) /// public BreadcrumbViewModel ActiveItem => _activeItem.Value; private readonly ObservableAsPropertyHelper _activeItem; #endregion /// /// Navigate to the subpath represented by the selected crumb which is passed as a parameter. /// Only this crumb and its ancestors are kept, the rest of the path is removed. /// public ReactiveCommand SelectCrumb { get; } public BreadcrumbBarViewModel() { SelectCrumb = ReactiveCommand.Create((BreadcrumbViewModel crumb) => { ActivePath.Edit(l => { int index = l.IndexOf(crumb); for (int i = l.Count - 1; i > index; i--) { l.RemoveAt(i); } }); }); ActivePath.Connect().Select(_ => ActivePath.Count > 0 ? ActivePath.Items.ElementAt(ActivePath.Count - 1) : null) .ToProperty(this, vm => vm.ActiveItem, out _activeItem); } } }