namespace SinMaiLauncher.CustomControls { public class AimeComboBox : ComboBox { private const int MaxDigits = 20; // 最大数字个数 private const int SegmentLen = 4; // 每段长度 private const int MaxLengthWithMask = 24; // 总长度(20数字 + 4连字符) public AimeComboBox() { InitializeControl(); } private void InitializeControl() { DropDownStyle = ComboBoxStyle.DropDown; // 允许手动输入 MaxLength = MaxLengthWithMask; // 设置最大长度 KeyPress += MaskedComboBox_KeyPress; TextChanged += MaskedComboBox_TextChanged; Leave += MaskedComboBox_Leave; } private void MaskedComboBox_KeyPress(object sender, KeyPressEventArgs e) { // 只允许输入数字和控制字符 if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar)) { e.Handled = true; } } private void MaskedComboBox_TextChanged(object sender, EventArgs e) { var text = Text.Replace("-", ""); // 移除现有连字符 var maskedText = ApplyMask(text); // 应用掩码 var cursorPosition = SelectionStart; // 保存光标位置 // 更新文本 Text = maskedText; // 调整光标位置 if (cursorPosition > 0 && cursorPosition < maskedText.Length) { if (maskedText[cursorPosition - 1] == '-') cursorPosition++; // 跳过连字符 SelectionStart = cursorPosition; } else { SelectionStart = maskedText.Length; } } private void MaskedComboBox_Leave(object sender, EventArgs e) { // 当离开控件时,确保输入完整 var text = Text.Replace("-", ""); if (text.Length > 0 && text.Length < MaxDigits) { text = text.PadRight(MaxDigits, '0'); // 不足20位补0 Text = ApplyMask(text); } } private string ApplyMask(string input) { // 提取数字并限制长度 var digits = new string(input.Where(char.IsDigit).Take(MaxDigits).ToArray()); var result = ""; // 应用掩码:0000-0000-0000-0000-0000 for (var i = 0; i < digits.Length; i++) { result += digits[i]; if ((i + 1) % SegmentLen == 0 && i < MaxDigits - 1) result += "-"; } return result; } // 可选:添加一个方法来设置预设选项 public void AddPresetOptions(string[] options) { foreach (var option in options) { if (IsValidMaskedFormat(option)) { Items.Add(option); } } } // 验证输入是否符合掩码格式 private bool IsValidMaskedFormat(string input) { return input.Length == MaxLengthWithMask && input.Split('-').Length == 5 && input.Replace("-", "").All(char.IsDigit); } } }