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.Input;
using System.Windows.Media;
using System.Globalization;
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,
PropertyChangedCallback = (d, e) =>
{
var self = (InputBar)d;
self.OnSelectionChanged();
}
});
public InputEntry? SelectedItem
{
get => GetValue(SelectedItemProperty) as InputEntry;
set => SetValue(SelectedItemProperty, value);
}
public static readonly DependencyProperty SelectedIndexProperty =
DependencyProperty.Register(nameof(SelectedIndex), typeof(int), typeof(InputBar), new FrameworkPropertyMetadata
{
BindsTwoWayByDefault = true,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
CoerceValueCallback = (d, baseObject) =>
{
var self = (InputBar)d;
return self.NormalizeIndex((int)baseObject);
}
});
public int SelectedIndex
{
get => (int)GetValue(SelectedIndexProperty);
set => SetValue(SelectedIndexProperty, value);
}
public InputBar()
{
InitializeComponent();
}
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Down:
SelectedIndex += 1;
ListBox.ScrollIntoView(ListBox.SelectedItem);
DropDown.IsOpen = true;
break;
case Key.Up:
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()
{
if (SelectedItem != null)
{
Text = SelectedItem.ToString();
TextBox.Select(Text.Length, 0);
}
}
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);
}
private void OnToggleDropDownButtonClick(object sender, RoutedEventArgs e)
{
TextBox.Focus();
TextBox.Select(Text?.Length ?? 0, 0);
if (!DropDown.IsOpen)
{
DropDown.IsOpen = true;
}
}
}
}