2

ユーザー入力をハイフンで区切られたチャンクに自動的に分割する、ある種のライセンス検証テキストボックスを作成しようとしています。私のライセンスは25文字の長さで、次のように区切られています。

XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

TextChanged私は、ユーザーが入力している間、またはテキストボックスコントロールのイベントを次のように処理することによってコピー/貼り付けを介してユーザー入力を解析するための次のコードを考え出しました。

public static string InsertStringAtInterval(string source, string insert, int interval)
        {
            StringBuilder result = new StringBuilder();
            int currentPosition = 0;
            while (currentPosition + interval < source.Length)
            {
                result.Append(source.Substring(currentPosition, interval)).Append(insert);
                currentPosition += interval;
            }
            if (currentPosition < source.Length)
            {
                result.Append(source.Substring(currentPosition));
            }
            return result.ToString();
        }

        private bool bHandlingChangeEvent = false;
        private void txtLicense_TextChanged(object sender, EventArgs e)
        {
            if (bHandlingChangeEvent == true)
                return;

            bHandlingChangeEvent = true;
            string text = txtLicense.Text.Replace("-", "").Replace(" ","");
            int nPos = txtLicense.SelectionStart;
            if((text.Length==5||text.Length==10||text.Length==15||text.Length==20) && txtLicense.Text[txtLicense.Text.Length-1]!='-')
            {
                txtLicense.Text += "-";
                txtLicense.SelectionStart = nPos + 1;
            }
            if(text.Length>=25)
            {
                string tmp = text.Substring(0, 25);
                tmp = InsertStringAtInterval(tmp, "-", 5);
                txtLicense.Text = tmp;
                txtLicense.SelectionStart = nPos;
            }


            bHandlingChangeEvent = false;
        }

これは、ユーザーがボックス内に入力して貼り付けるときに完全に機能します。私の唯一の問題は、ユーザーがバックスペースまたは削除を押して、入力したキーから文字を削除しようとしたときです。

ユーザーがバックスペースでこれらのマークの1つに到達すると、位置5、10、15、20でハイフンが強制的に挿入されるため、上記のロジックを押すと、文字列にハイフンが追加され、ユーザーはそれを超えることはできません。

KeyDownイベントをいじってみましたが、役立つものが見つかりませんでした。誰か助けてくれませんか。

MaskedTextboxも使用してみましたが、フォーカスにマスク/ハイフンを表示したくないので、それは醜いです。プロンプトの内側をクリックすると混乱が生じるため、プロンプトを空白に置き換えたくありません。ボックスは、「おそらく」空の場合、カーソルが常にボックスの先頭に配置されるとは限りません。

4

3 に答える 3

2

このバージョンを試すことができます:

void txtLicense_KeyDown(object sender, KeyEventArgs e) {
  if (e.KeyCode == Keys.Back) {

    int index = txtLicense.SelectionStart;
    while (index > 0 && txtLicense.Text[index - 1] == '-') {
      --index;
    }

    if (index > 0) {
      --index;
    }

    txtLicense.Select(index, txtLicense.SelectionLength + Math.Max(index, 1));
    txtLicense.SelectedText = string.Empty;

    e.SuppressKeyPress = true;
  }
}
于 2013-03-06T15:47:19.753 に答える
2

このようなことは、私にとって何年にもわたって多くの苦しみの原因となってきました。私がアプローチする方法は、テキストへの各変更を最初から貼り付けたように扱うことです。ハイフンを取り除き、適切な位置に戻します。次に、ユーザーが最後の文字を削除したという特殊なケースを処理できます。この場合、TextChangedイベントの直前のテキストと後のテキストを比較します。それらが同じであるが、前のテキストが1文字長い場合は、特別なことは何もしないでください。

これは、テキスト入力、切り取り/コピー/貼り付けなどで機能するように見えるコードです。少し凝ったLINQやエラー処理などで改善できる可能性がありますが、うまくいけば、アイデアが伝わります。

private string previousText = string.Empty;
private bool processing = false;

private void textBox1_TextChanged(object sender, EventArgs e)
{
    // If we're already messing around with the text, don't start again.
    if (processing)
        return;

    processing = true;

    // The current textbox text
    string newText = textBox1.Text;

    // What was there before, minus one character.
    string previousLessOne = previousText == string.Empty ? string.Empty : previousText.Substring(0, previousText.Length - 1);

    // Get where the user is, minus any preceding dashes
    int caret = textBox1.SelectionStart - (textBox1.Text.Substring(0, textBox1.SelectionStart).Count(ch => ch == '-'));

    // If the user has done anything other than delete the last character, ensure dashes are placed in the correct position.
    if (newText.Length > 0 && newText != previousLessOne)
    {
        textBox1.Text = string.Empty;
        newText = newText.Replace("-", "");

        for (int i = 0; i < newText.Length; i += 5)
        {
            int length = Math.Min(newText.Length - i, 5);
            textBox1.Text += newText.Substring(i, length);

            if (length == 5)
                textBox1.Text += '-';
        }
    }

    // Put the user back where they were, adjusting for dashes.
    textBox1.SelectionStart = caret + (caret / 5);

    previousText = textBox1.Text;

    processing = false;
}
于 2013-03-06T16:59:12.423 に答える
1

私は以前にこれに似た何かをしました。挿入ポイントの後に文字が表示されるまで、ハイフンを追加しません。たとえば、5文字を入力した後にハイフンを追加する代わりに、6文字でハイフンを追加して、最後に追加されないようにします。

特定の場所にハイフンを挿入するために使用するアルゴリズムは次のとおりです。

public static string FormatLicenseNumber(string str)
{
    if (string.IsNullOrEmpty(str))
        return str;
    else
    {
        str = str.Replace("-", string.Empty);
        if (str.Length > 20)
            str = str.Insert(20, "-");
        if (str.Length > 15)
            str = str.Insert(15, "-");
        if (str.Length > 10)
            str = str.Insert(10, "-");
        if (str.Length > 5)
            str = str.Insert(5, "-");
        return str;
    }
}
于 2013-03-06T15:48:17.390 に答える