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
{
///
/// InputBar.xaml 的交互逻辑
///
[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), typeof(InputBar), new FrameworkPropertyMetadata
{
BindsTwoWayByDefault = true,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
CoerceValueCallback = (d, baseObject) =>
{
var value = baseObject as IEnumerable;
if (value?.Count() > 100)
{
value = value
.Take(99)
.Append(new InputEntry(InputEntryType.Path, $"Other {value.Count() - 50} items...", string.Empty));
}
return value;
}
});
public IEnumerable? Collection
{
get => GetValue(CollectionProperty) as IEnumerable;
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);
}
}
}