3

null値を格納できるかのようにTextBoxを動作させています。それを行うために、値が保存されているかどうかを示す変数 NullMode が Null であり、TextChanged でそれを false に設定し、特定のユーザー アクションで true に設定し、Text を存在することを示す値に設定します。テキストボックス内は null です。次に、NullMode に基づいて、テキスト ボックスが別の方法で描画されます。

今、私は必要のないときにイベントハンドルが発火するのを防ぐために、セマフォのようなアプローチをとっています。これがどのように見えるかです:

                private void input_TextChanged(object sender, EventArgs e)
        {
            if (_preventTextBoxEvents) 
                return;

            _preventTextBoxEvents = true;

            //if (NullMode)
            //  Text = "";
            NullMode = false;
            ValidateInput();

            _preventTextBoxEvents = false;
        }

ここで、nullmode のときに表示するテキスト ボックスのテキストを設定する必要がある場合は、true にする前に _preventTextBoxEvents を設定するだけで問題なく動作します。

しかし!ユーザーがテキストボックスに何かを入力しようとしたときに、テキストも削除する必要があります! したがって、テキストを "" に設定する必要があります。問題は、コメントを外すと、イベントハンドラーが終了した後にフォームが閉じられることです。私はそれを防ぐことができず (e.Cancel = true in FormClosing は役に立たない!)、何が原因なのか理解できません。エラーメッセージもありません(そして、私はtry-catchをしていません)。

私のロジックは、Text="" を実行するときです。OnTextChanged が起動し、TextChanged を呼び出す必要があり、_preventTextBoxEvents が true であることを確認して終了するため、スタック オーバーフローや無限再帰は発生しません。

何が起こっている?

4

1 に答える 1

3

そうあるべきです(テキストボックスが呼び出されていると仮定しますinput

if (NullMode) 
    input.Text = ""; 

テキストのみは、input.Text プロパティではなく、現在のフォーム キャプションを参照します。
ただし、あなたのアプローチは危険です。何らかの理由で ValidateInput が例外をスローした場合、グローバル _preventTextBoxEvents を false に戻さずにイベント ハンドラーを終了します。

try - catch - 最後に追加

    private void input_TextChanged(object sender, EventArgs e)   
    {   
        if (_preventTextBoxEvents)    
            return;   

        _preventTextBoxEvents = true;   
        try
        {
           if (NullMode) input.Text = "";   
           NullMode = false;   
           ValidateInput();   
        }
        catch(Exception ex)
        {
            // Inform user of the exception occurred inside your ValidateInput
            MessageBox.Show(ex.Message);
        }
        finally
        {
            // Be sure to restore this global to a functioning value.
            _preventTextBoxEvents = false;   
        }
    }   

さらに、 _preventTextBoxEventsのロジックを削除して、プログラムがイベント コードに入ったときに TextChanged イベントを単に切断することもできます。

try
{
    input.TextChanged -= new EventArgs(input_TextChanged);
    // Now, the input textbox is no more connected to this code, you 
    // could happily change the textbox text without worry to reenter in this code
}
...
finally
{
    // Work finished, reconnect this code to the event TextChanged
    input.TextChanged += new EventArgs(input_TextChanged);
}
于 2012-04-14T11:40:01.557 に答える