151 lines
5.1 KiB
C#
151 lines
5.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
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 System.Diagnostics;
|
|
|
|
namespace HashCalculator.GUI
|
|
{
|
|
/// <summary>
|
|
/// InputBar.xaml 的交互逻辑
|
|
/// </summary>
|
|
[SuppressMessage("Microsoft.Performance", "CA1812")]
|
|
internal partial class InputBar : UserControl
|
|
{
|
|
public static readonly DependencyProperty HintTextProperty =
|
|
DependencyProperty.Register(nameof(HintText), typeof(string), typeof(InputBar), new FrameworkPropertyMetadata
|
|
{
|
|
BindsTwoWayByDefault = true,
|
|
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
|
|
});
|
|
public string? HintText
|
|
{
|
|
get => GetValue(HintTextProperty) as string;
|
|
set => SetValue(HintTextProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty TextProperty =
|
|
DependencyProperty.Register(nameof(Text), typeof(string), typeof(InputBar), new FrameworkPropertyMetadata
|
|
{
|
|
BindsTwoWayByDefault = true,
|
|
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
|
|
});
|
|
public string? Text
|
|
{
|
|
get => GetValue(TextProperty) as string;
|
|
set => SetValue(TextProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty CollectionProperty =
|
|
DependencyProperty.Register(nameof(Collection), typeof(IEnumerable<InputEntry>), typeof(InputBar), new FrameworkPropertyMetadata
|
|
{
|
|
BindsTwoWayByDefault = true,
|
|
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
|
|
CoerceValueCallback = (d, baseObject) =>
|
|
{
|
|
var value = baseObject as IEnumerable<InputEntry>;
|
|
if (value?.Count() > 100)
|
|
{
|
|
value = value
|
|
.Take(99)
|
|
.Append(new InputEntry(InputEntryType.Path, $"Other {value.Count() - 50} items...", string.Empty));
|
|
}
|
|
return value;
|
|
}
|
|
});
|
|
public IEnumerable<InputEntry>? Collection
|
|
{
|
|
get => GetValue(CollectionProperty) as IEnumerable<InputEntry>;
|
|
set => SetValue(CollectionProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty SelectedItemProperty =
|
|
DependencyProperty.Register(nameof(SelectedItem), typeof(InputEntry), typeof(InputBar), new FrameworkPropertyMetadata
|
|
{
|
|
BindsTwoWayByDefault = true,
|
|
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
|
|
});
|
|
public InputEntry? SelectedItem
|
|
{
|
|
get => GetValue(SelectedItemProperty) as InputEntry;
|
|
set => SetValue(SelectedItemProperty, value);
|
|
}
|
|
|
|
public event TextChangedEventHandler? TextChanged;
|
|
|
|
public InputBar()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
switch (e.Key)
|
|
{
|
|
case Key.Down:
|
|
ListBox.SelectedIndex = NormalizeIndex(ListBox.SelectedIndex + 1);
|
|
ListBox.ScrollIntoView(ListBox.SelectedItem);
|
|
DropDown.IsOpen = true;
|
|
break;
|
|
case Key.Up:
|
|
ListBox.SelectedIndex = NormalizeIndex(ListBox.SelectedIndex - 1);
|
|
ListBox.ScrollIntoView(ListBox.SelectedItem);
|
|
break;
|
|
case Key.Escape:
|
|
case Key.Enter:
|
|
DropDown.IsOpen = false;
|
|
break;
|
|
default:
|
|
DropDown.IsOpen = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
{
|
|
SelectedItem = (InputEntry)ListBox.SelectedItem;
|
|
if (SelectedItem != null)
|
|
{
|
|
Text = SelectedItem.ToString();
|
|
TextBox.Select(Text.Length, 0);
|
|
}
|
|
}
|
|
|
|
private void OnTextChanged(object sender, TextChangedEventArgs e)
|
|
{
|
|
if (Text != SelectedItem?.ToString())
|
|
{
|
|
TextChanged?.Invoke(this, e);
|
|
}
|
|
}
|
|
|
|
private void OnLostFocus(object sender, RoutedEventArgs e)
|
|
{
|
|
DropDown.IsOpen = false;
|
|
}
|
|
|
|
private int NormalizeIndex(int rawIndex)
|
|
{
|
|
if (Collection == null)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return Math.Min(Math.Max(rawIndex, -1), Collection.Count() - 1);
|
|
}
|
|
|
|
|
|
}
|
|
}
|