166 lines
5.6 KiB
C#
166 lines
5.6 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.Input;
|
|
using System.Windows.Media;
|
|
using System.Globalization;
|
|
|
|
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,
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|