AimeComboBox.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. namespace SinMaiLauncher.CustomControls
  2. {
  3. public class AimeComboBox : ComboBox
  4. {
  5. private const int MaxDigits = 20; // 最大数字个数
  6. private const int SegmentLen = 4; // 每段长度
  7. private const int MaxLengthWithMask = 24; // 总长度(20数字 + 4连字符)
  8. public AimeComboBox()
  9. {
  10. InitializeControl();
  11. }
  12. private void InitializeControl()
  13. {
  14. DropDownStyle = ComboBoxStyle.DropDown; // 允许手动输入
  15. MaxLength = MaxLengthWithMask; // 设置最大长度
  16. KeyPress += MaskedComboBox_KeyPress;
  17. TextChanged += MaskedComboBox_TextChanged;
  18. Leave += MaskedComboBox_Leave;
  19. }
  20. private void MaskedComboBox_KeyPress(object sender, KeyPressEventArgs e)
  21. {
  22. // 只允许输入数字和控制字符
  23. if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
  24. {
  25. e.Handled = true;
  26. }
  27. }
  28. private void MaskedComboBox_TextChanged(object sender, EventArgs e)
  29. {
  30. var text = Text.Replace("-", ""); // 移除现有连字符
  31. var maskedText = ApplyMask(text); // 应用掩码
  32. var cursorPosition = SelectionStart; // 保存光标位置
  33. // 更新文本
  34. Text = maskedText;
  35. // 调整光标位置
  36. if (cursorPosition > 0 && cursorPosition < maskedText.Length)
  37. {
  38. if (maskedText[cursorPosition - 1] == '-')
  39. cursorPosition++; // 跳过连字符
  40. SelectionStart = cursorPosition;
  41. }
  42. else
  43. {
  44. SelectionStart = maskedText.Length;
  45. }
  46. }
  47. private void MaskedComboBox_Leave(object sender, EventArgs e)
  48. {
  49. // 当离开控件时,确保输入完整
  50. var text = Text.Replace("-", "");
  51. if (text.Length > 0 && text.Length < MaxDigits)
  52. {
  53. text = text.PadRight(MaxDigits, '0'); // 不足20位补0
  54. Text = ApplyMask(text);
  55. }
  56. }
  57. private string ApplyMask(string input)
  58. {
  59. // 提取数字并限制长度
  60. var digits = new string(input.Where(char.IsDigit).Take(MaxDigits).ToArray());
  61. var result = "";
  62. // 应用掩码:0000-0000-0000-0000-0000
  63. for (var i = 0; i < digits.Length; i++)
  64. {
  65. result += digits[i];
  66. if ((i + 1) % SegmentLen == 0 && i < MaxDigits - 1)
  67. result += "-";
  68. }
  69. return result;
  70. }
  71. // 可选:添加一个方法来设置预设选项
  72. public void AddPresetOptions(string[] options)
  73. {
  74. foreach (var option in options)
  75. {
  76. if (IsValidMaskedFormat(option))
  77. {
  78. Items.Add(option);
  79. }
  80. }
  81. }
  82. // 验证输入是否符合掩码格式
  83. private bool IsValidMaskedFormat(string input)
  84. {
  85. return input.Length == MaxLengthWithMask && input.Split('-').Length == 5 &&
  86. input.Replace("-", "").All(char.IsDigit);
  87. }
  88. }
  89. }