port from perforce
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using DynamicData;
|
||||
using NodeNetwork.Utilities;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ContextMenu
|
||||
{
|
||||
public partial class SearchableContextMenuView : IViewFor<SearchableContextMenuViewModel>
|
||||
{
|
||||
#region ViewModel
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(SearchableContextMenuViewModel), typeof(SearchableContextMenuView), new PropertyMetadata(null));
|
||||
|
||||
public SearchableContextMenuViewModel ViewModel
|
||||
{
|
||||
get => (SearchableContextMenuViewModel)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (SearchableContextMenuViewModel)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ChildrenBelowSearch
|
||||
public static readonly DependencyProperty ChildrenBelowSearchProperty =
|
||||
DependencyProperty.Register(nameof(ChildrenBelowSearch), typeof(IEnumerable), typeof(SearchableContextMenuView), new PropertyMetadata(new object[0]));
|
||||
|
||||
public IEnumerable ChildrenBelowSearch
|
||||
{
|
||||
get => (IEnumerable)GetValue(ChildrenBelowSearchProperty);
|
||||
set => SetValue(ChildrenBelowSearchProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReferencePointElement
|
||||
public static readonly DependencyProperty ReferencePointElementProperty =
|
||||
DependencyProperty.Register(nameof(ReferencePointElement), typeof(IInputElement), typeof(SearchableContextMenuView), new PropertyMetadata(null));
|
||||
|
||||
public IInputElement ReferencePointElement
|
||||
{
|
||||
get => (IInputElement)GetValue(ReferencePointElementProperty);
|
||||
set => SetValue(ReferencePointElementProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OpenPoint
|
||||
public static readonly DependencyProperty OpenPointProperty =
|
||||
DependencyProperty.Register(nameof(OpenPoint), typeof(Point), typeof(SearchableContextMenuView), new PropertyMetadata(new Point()));
|
||||
|
||||
public Point OpenPoint
|
||||
{
|
||||
get => (Point)GetValue(OpenPointProperty);
|
||||
private set => SetValue(OpenPointProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public SearchableContextMenuView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SearchQuery, v => v.SearchTextBox.Text);
|
||||
this.BindList(ViewModel, vm => vm.VisibleCommands, v => v.CollectionContainer.Collection);
|
||||
|
||||
Binding myBinding = new Binding(nameof(ChildrenBelowSearch)) { Source = this };
|
||||
BindingOperations.SetBinding(ContainerBelowSearch, CollectionContainer.CollectionProperty, myBinding);
|
||||
|
||||
this.Opened += (sender, args) =>
|
||||
{
|
||||
SearchTextBox.Focus();
|
||||
if (ReferencePointElement != null)
|
||||
{
|
||||
OpenPoint = Mouse.GetPosition(ReferencePointElement);
|
||||
}
|
||||
};
|
||||
|
||||
// This var is needed to ensure both key down and key up of arrow keys happened in the textbox,
|
||||
// otherwise moving into the textbox will immediately move out again.
|
||||
bool arrowWasPressedInTextBox = false;
|
||||
|
||||
this.SearchTextBox.PreviewKeyDown += (sender, args) =>
|
||||
{
|
||||
if (args.Key == Key.Enter || args.Key == Key.Return)
|
||||
{
|
||||
if (ViewModel.VisibleCommands.Count > 0)
|
||||
{
|
||||
var firstEntry = ViewModel.VisibleCommands.Items.First();
|
||||
firstEntry.Command.Execute(firstEntry.CommandParameter);
|
||||
this.IsOpen = false;
|
||||
}
|
||||
}
|
||||
else if (args.Key == Key.Escape && SearchTextBox.Text.Length > 0)
|
||||
{
|
||||
SearchTextBox.Text = "";
|
||||
args.Handled = true;
|
||||
}
|
||||
else if (args.Key == Key.Up || args.Key == Key.Down)
|
||||
{
|
||||
arrowWasPressedInTextBox = true;
|
||||
}
|
||||
};
|
||||
this.SearchTextBox.PreviewKeyUp += (sender, args) =>
|
||||
{
|
||||
if (arrowWasPressedInTextBox && (args.Key == Key.Up || args.Key == Key.Down))
|
||||
{
|
||||
arrowWasPressedInTextBox = false;
|
||||
|
||||
var dir = args.Key == Key.Up ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next;
|
||||
var traversalRequest = new TraversalRequest(dir);
|
||||
var focusedElem = Keyboard.FocusedElement as FrameworkElement;
|
||||
focusedElem?.MoveFocus(traversalRequest);
|
||||
}
|
||||
};
|
||||
this.SearchMenuItem.GotKeyboardFocus += (sender, args) => { SearchTextBox.Focus(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user