Merge pull request #773 from yangjieshao/fix_issues_590

修复 IPv4Box PinCode TimeBox  对 Delete 键的支持
This commit is contained in:
Dong Bin
2025-09-19 14:45:59 +08:00
committed by GitHub
3 changed files with 118 additions and 32 deletions

View File

@@ -26,7 +26,7 @@ public enum IPv4BoxInputMode
[TemplatePart(PART_SecondTextPresenter, typeof(TextPresenter))] [TemplatePart(PART_SecondTextPresenter, typeof(TextPresenter))]
[TemplatePart(PART_ThirdTextPresenter, typeof(TextPresenter))] [TemplatePart(PART_ThirdTextPresenter, typeof(TextPresenter))]
[TemplatePart(PART_FourthTextPresenter, typeof(TextPresenter))] [TemplatePart(PART_FourthTextPresenter, typeof(TextPresenter))]
public class IPv4Box: TemplatedControl public class IPv4Box : TemplatedControl
{ {
public const string PART_FirstTextPresenter = "PART_FirstTextPresenter"; public const string PART_FirstTextPresenter = "PART_FirstTextPresenter";
public const string PART_SecondTextPresenter = "PART_SecondTextPresenter"; public const string PART_SecondTextPresenter = "PART_SecondTextPresenter";
@@ -42,7 +42,7 @@ public class IPv4Box: TemplatedControl
private byte? _fourthByte; private byte? _fourthByte;
private readonly TextPresenter?[] _presenters = new TextPresenter?[4]; private readonly TextPresenter?[] _presenters = new TextPresenter?[4];
private TextPresenter? _currentActivePresenter; private TextPresenter? _currentActivePresenter;
public static readonly StyledProperty<IPAddress?> IPAddressProperty = AvaloniaProperty.Register<IPv4Box, IPAddress?>( public static readonly StyledProperty<IPAddress?> IPAddressProperty = AvaloniaProperty.Register<IPv4Box, IPAddress?>(
nameof(IPAddress), defaultBindingMode: BindingMode.TwoWay); nameof(IPAddress), defaultBindingMode: BindingMode.TwoWay);
public IPAddress? IPAddress public IPAddress? IPAddress
@@ -111,7 +111,7 @@ public class IPv4Box: TemplatedControl
/// <summary> /// <summary>
/// 是否使用小键盘输入 /// 是否使用小键盘输入
/// </summary> /// </summary>
internal bool IsTargetByNumPad internal bool IsTargetByNumPad
{ {
set set
{ {
@@ -152,7 +152,7 @@ public class IPv4Box: TemplatedControl
ParseBytes(ShowLeadingZero); ParseBytes(ShowLeadingZero);
} }
} }
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {
_currentActivePresenter ??= _presenters[0]; _currentActivePresenter ??= _presenters[0];
@@ -214,7 +214,13 @@ public class IPv4Box: TemplatedControl
if (e.Key == Key.Back) if (e.Key == Key.Back)
{ {
DeleteImplementation(_currentActivePresenter); DeleteImplementation(_currentActivePresenter, isDeleteKey: false);
e.Handled = true;
return;
}
if (e.Key == Key.Delete)
{
DeleteImplementation(_currentActivePresenter, isDeleteKey: true);
e.Handled = true; e.Handled = true;
return; return;
} }
@@ -234,7 +240,7 @@ public class IPv4Box: TemplatedControl
} }
base.OnKeyDown(e); base.OnKeyDown(e);
} }
protected override void OnTextInput(TextInputEventArgs e) protected override void OnTextInput(TextInputEventArgs e)
{ {
if (e.Handled) return; if (e.Handled) return;
@@ -291,7 +297,7 @@ public class IPv4Box: TemplatedControl
} }
} }
} }
protected override void OnPointerPressed(PointerPressedEventArgs e) protected override void OnPointerPressed(PointerPressedEventArgs e)
{ {
Point position = e.GetPosition(_firstText); Point position = e.GetPosition(_firstText);
@@ -413,7 +419,7 @@ public class IPv4Box: TemplatedControl
if (_fourthText != null) _fourthText.Text = _fourthByte?.ToString(format); if (_fourthText != null) _fourthText.Text = _fourthByte?.ToString(format);
} }
private bool MoveToNextPresenter(TextPresenter? presenter, bool selectAllAfterMove) private bool MoveToNextPresenter(TextPresenter? presenter, bool selectAllAfterMove)
{ {
@@ -451,7 +457,7 @@ public class IPv4Box: TemplatedControl
_fourthByte = null; _fourthByte = null;
IPAddress = null; IPAddress = null;
} }
private void SetIPAddressInternal() private void SetIPAddressInternal()
{ {
if (_firstByte is null && _secondByte is null && _thirdByte is null && _fourthByte is null) if (_firstByte is null && _secondByte is null && _thirdByte is null && _fourthByte is null)
@@ -474,31 +480,69 @@ public class IPv4Box: TemplatedControl
} }
} }
private void DeleteImplementation(TextPresenter? presenter) /// <summary>
/// </summary>
/// <param name="presenter"></param>
/// <param name="isDeleteKey">del 键 (从前往后删)</param>
private void DeleteImplementation(TextPresenter? presenter, bool isDeleteKey)
{ {
if(presenter is null) return; if (presenter is null) return;
var oldText = presenter.Text ?? string.Empty; var oldText = presenter.Text ?? string.Empty;
if (presenter.SelectionStart != presenter.SelectionEnd) if (presenter.SelectionStart != presenter.SelectionEnd)
{ {
presenter.DeleteSelection(); presenter.DeleteSelection();
presenter.ClearSelection(); presenter.ClearSelection();
} }
else if (string.IsNullOrWhiteSpace(oldText) || presenter.CaretIndex == 0) else if (isDeleteKey)
{ {
presenter.HideCaret(); if (string.IsNullOrWhiteSpace(oldText) || presenter.CaretIndex == oldText.Length)
MoveToPreviousTextPresenter(presenter);
if (_currentActivePresenter != null)
{ {
_currentActivePresenter.ShowCaret(); presenter.HideCaret();
_currentActivePresenter.MoveCaretToEnd(); var oldActivePresenter = _currentActivePresenter;
MoveToNextPresenter(presenter, selectAllAfterMove: false);
if (_currentActivePresenter != null)
{
_currentActivePresenter.ShowCaret();
if (!ReferenceEquals(oldActivePresenter, _currentActivePresenter))
{
_currentActivePresenter.MoveCaretToStart();
}
}
}
else
{
var index = presenter.CaretIndex;
var newText = string.Empty;
if (index == 0)
{
newText = oldText.Substring(1, oldText.Length - 1);
}
else
{
newText = oldText.Substring(0, index) + oldText.Substring(index + 1);
}
presenter.Text = newText;
} }
} }
else else
{ {
int index = presenter.CaretIndex; if (string.IsNullOrWhiteSpace(oldText) || presenter.CaretIndex == 0)
string newText = oldText.Substring(0, index - 1) + oldText.Substring(Math.Min(index, oldText.Length)); {
presenter.MoveCaretHorizontal(LogicalDirection.Backward); presenter.HideCaret();
presenter.Text = newText; MoveToPreviousTextPresenter(presenter);
if (_currentActivePresenter != null)
{
_currentActivePresenter.ShowCaret();
_currentActivePresenter.MoveCaretToEnd();
}
}
else
{
int index = presenter.CaretIndex;
string newText = oldText.Substring(0, index - 1) + oldText.Substring(Math.Min(index, oldText.Length));
presenter.MoveCaretHorizontal(LogicalDirection.Backward);
presenter.Text = newText;
}
} }
} }
@@ -565,7 +609,7 @@ public class IPv4Box: TemplatedControl
if (clipboard is null) return; if (clipboard is null) return;
await clipboard.SetTextAsync(s); await clipboard.SetTextAsync(s);
} }
public static KeyGesture? CopyKeyGesture { get; } = Application.Current?.PlatformSettings?.HotkeyConfiguration.Copy.FirstOrDefault(); public static KeyGesture? CopyKeyGesture { get; } = Application.Current?.PlatformSettings?.HotkeyConfiguration.Copy.FirstOrDefault();
public static KeyGesture? PasteKeyGesture { get; } = Application.Current?.PlatformSettings?.HotkeyConfiguration.Paste.FirstOrDefault(); public static KeyGesture? PasteKeyGesture { get; } = Application.Current?.PlatformSettings?.HotkeyConfiguration.Paste.FirstOrDefault();
public static KeyGesture? CutKeyGesture { get; } = Application.Current?.PlatformSettings?.HotkeyConfiguration.Cut.FirstOrDefault(); public static KeyGesture? CutKeyGesture { get; } = Application.Current?.PlatformSettings?.HotkeyConfiguration.Cut.FirstOrDefault();

View File

@@ -161,7 +161,6 @@ public class PinCode : TemplatedControl
protected async void OnPreviewKeyDown(KeyEventArgs e) protected async void OnPreviewKeyDown(KeyEventArgs e)
{ {
TextBox b = new TextBox();
var pasteKeys = Application.Current?.PlatformSettings?.HotkeyConfiguration.Paste; var pasteKeys = Application.Current?.PlatformSettings?.HotkeyConfiguration.Paste;
if (pasteKeys?.Any(a => a.Matches(e)) == true) if (pasteKeys?.Any(a => a.Matches(e)) == true)
{ {
@@ -209,6 +208,17 @@ public class PinCode : TemplatedControl
_currentIndex--; _currentIndex--;
_itemsControl?.ContainerFromIndex(_currentIndex)?.Focus(); _itemsControl?.ContainerFromIndex(_currentIndex)?.Focus();
} }
else if (e.Key == Key.Delete && _currentIndex < Digits.Count)
{
_currentIndex = MathHelpers.SafeClamp(_currentIndex, 0, Count - 1);
var presenter = _itemsControl?.ContainerFromIndex(_currentIndex) as PinCodeItem;
if (presenter is null) return;
Digits[_currentIndex] = string.Empty;
presenter.Text = string.Empty;
if (_currentIndex == Digits.Count-1) return;
_currentIndex++;
_itemsControl?.ContainerFromIndex(_currentIndex)?.Focus();
}
else if (e.Key is Key.Left or Key.FnLeftArrow) else if (e.Key is Key.Left or Key.FnLeftArrow)
{ {
_currentIndex--; _currentIndex--;

View File

@@ -251,7 +251,11 @@ public class TimeBox : TemplatedControl
} }
else if (e.Key == Key.Back) else if (e.Key == Key.Back)
{ {
DeleteImplementation(_currentActiveSectionIndex.Value); DeleteImplementation(_currentActiveSectionIndex.Value, isDeleteKey: false);
}
else if (e.Key == Key.Delete)
{
DeleteImplementation(_currentActiveSectionIndex.Value, isDeleteKey: true);
} }
else if (e.Key == Key.Right) else if (e.Key == Key.Right)
{ {
@@ -596,7 +600,11 @@ public class TimeBox : TemplatedControl
} }
} }
private void DeleteImplementation(int index) /// <summary>
/// </summary>
/// <param name="index"></param>
/// <param name="isDeleteKey">del 键 (从前往后删)</param>
private void DeleteImplementation(int index, bool isDeleteKey)
{ {
if (index < 0 || index > 3) return; if (index < 0 || index > 3) return;
var oldText = _presenters[index].Text??string.Empty; var oldText = _presenters[index].Text??string.Empty;
@@ -605,17 +613,41 @@ public class TimeBox : TemplatedControl
_presenters[index].DeleteSelection(); _presenters[index].DeleteSelection();
_presenters[index].ClearSelection(); _presenters[index].ClearSelection();
} }
else if (string.IsNullOrWhiteSpace(oldText) || _presenters[index].CaretIndex == 0) else if (isDeleteKey)
{ {
MoveToPreviousSection(index); if (string.IsNullOrWhiteSpace(oldText) || _presenters[index].CaretIndex == oldText.Length)
{
MoveToNextSection(index);
}
else
{
int caretIndex = _presenters[index].CaretIndex;
var newText = string.Empty;
if (caretIndex == 0)
{
newText = oldText.Substring(1, oldText.Length - 1);
}
else
{
newText = oldText.Substring(0, caretIndex) + oldText.Substring(caretIndex + 1);
}
_presenters[index].Text = newText;
}
} }
else else
{ {
int caretIndex = _presenters[index].CaretIndex; if (string.IsNullOrWhiteSpace(oldText) || _presenters[index].CaretIndex == 0)
string newText = oldText.Substring(0, caretIndex - 1) + {
oldText.Substring(Math.Min(caretIndex, oldText.Length)); MoveToPreviousSection(index);
_presenters[index].MoveCaretHorizontal(LogicalDirection.Backward); }
_presenters[index].Text = newText; else
{
int caretIndex = _presenters[index].CaretIndex;
string newText = oldText.Substring(0, caretIndex - 1) +
oldText.Substring(Math.Min(caretIndex, oldText.Length));
_presenters[index].MoveCaretHorizontal(LogicalDirection.Backward);
_presenters[index].Text = newText;
}
} }
} }