port from perforce
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<UserControl x:Class="NodeNetwork.Toolkit.BreadcrumbBar.BreadcrumbBarView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<ListView x:Name="list" SelectionMode="Single">
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Data="M 0,0 L 2.5,2.5 L 0,5" Margin="0,2,6,0" StrokeThickness="2" Stroke="#555555" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Name}" TextAlignment="Center" VerticalAlignment="Stretch"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using NodeNetwork.Utilities;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Legacy;
|
||||
|
||||
namespace NodeNetwork.Toolkit.BreadcrumbBar
|
||||
{
|
||||
public partial class BreadcrumbBarView : UserControl, IViewFor<BreadcrumbBarViewModel>
|
||||
{
|
||||
#region ViewModel
|
||||
public static readonly DependencyProperty ViewModelProperty =
|
||||
DependencyProperty.Register(nameof(ViewModel), typeof(BreadcrumbBarViewModel), typeof(BreadcrumbBarView), new PropertyMetadata(null));
|
||||
|
||||
public BreadcrumbBarViewModel ViewModel
|
||||
{
|
||||
get => (BreadcrumbBarViewModel)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (BreadcrumbBarViewModel)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public BreadcrumbBarView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.BindList(ViewModel, vm => vm.ActivePath, v => v.list.ItemsSource).DisposeWith(d);
|
||||
this.WhenAnyValue(v => v.list.SelectedItem)
|
||||
.Where(i => i != null)
|
||||
.Cast<BreadcrumbViewModel>()
|
||||
.Do(_ => list.UnselectAll())
|
||||
.InvokeCommand(this, v => v.ViewModel.SelectCrumb).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using DynamicData;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.BreadcrumbBar
|
||||
{
|
||||
/// <summary>
|
||||
/// Viewmodel for a single element of the BreadcrumbBar.
|
||||
/// </summary>
|
||||
public class BreadcrumbViewModel : ReactiveObject
|
||||
{
|
||||
#region Name
|
||||
/// <summary>
|
||||
/// Displayed name of the crumb.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => this.RaiseAndSetIfChanged(ref _name, value);
|
||||
}
|
||||
private string _name = "";
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel for the BreadcrumbBar.
|
||||
/// This UI element displays a path as a list of path elements (crumbs), allowing navigation by selection of path elements.
|
||||
/// </summary>
|
||||
public class BreadcrumbBarViewModel : ReactiveObject
|
||||
{
|
||||
static BreadcrumbBarViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new BreadcrumbBarView(), typeof(IViewFor<BreadcrumbBarViewModel>));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The path that is currently displayed in the bar.
|
||||
/// Add or remove elements to modify the path.
|
||||
/// </summary>
|
||||
public ISourceList<BreadcrumbViewModel> ActivePath { get; } = new SourceList<BreadcrumbViewModel>();
|
||||
|
||||
#region ActiveElement
|
||||
/// <summary>
|
||||
/// The deepest element of the currect path. (Last element of ActivePath)
|
||||
/// </summary>
|
||||
public BreadcrumbViewModel ActiveItem => _activeItem.Value;
|
||||
private readonly ObservableAsPropertyHelper<BreadcrumbViewModel> _activeItem;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public ReactiveCommand<BreadcrumbViewModel, Unit> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user