46

私はC#を使用しています。編集ボックスと[キャンセル]ボタンのあるWindowsフォームがあります。編集ボックスには、イベントを検証するためのコードがあります。編集ボックスがフォーカスを失うたびに、コードが実行されます。[キャンセル]ボタンをクリックすると、フォームを閉じたいだけです。編集ボックスの検証を実行したくありません。これはどのように達成できますか?

ここに重要な詳細があります:検証が​​失敗した場合、

            e.Cancel = true;

コントロールを離れることを防ぎます。

ただし、ユーザーが[キャンセル]ボタンをクリックすると、何があってもフォームを閉じる必要があります。これはどのように実装できますか?

4

17 に答える 17

50

編集ボックスがフォーカスを失ったときに検証が発生した場合、キャンセル ボタンについては何も起こらないようにします。

ただし、検証の失敗によってキャンセル ボタンが機能しない場合はCausesValidation、ボタンのプロパティを に設定しますfalse

参考:Button.CausesValidation物件

于 2009-12-10T17:19:06.807 に答える
35

明らかCausesValidationに、ボタンのプロパティを false に設定する必要があり、クリック時に検証イベントが発生することはありません。ただし、ボタンの親コントロールのCausesValidationプロパティが true に設定されている場合、これは失敗する可能性があります。CausesValidationほとんどの場合、開発者はコンテナー コントロール (パネル コントロールなど)のプロパティを変更するのを見逃したり忘れたりします。これも False に設定します。そして、それはうまくいくはずです。

于 2010-03-26T21:06:14.150 に答える
23

特定のコントロールの検証がフォームを停止していたため、フォームを閉じるのに問題がありました。control.CausesValidation = falseキャンセル ボタンとキャンセル ボタンのすべての親に を設定しました。しかし、まだ問題がありました。

ユーザーがバリデーションを使用しているフィールドを編集している最中に、編集を中止する (フィールドに無効な入力を残す) ことを決定した場合、キャンセル ボタン イベントが発生しているように見えましたが、ウィンドウは閉じませんでした。

これは、キャンセル ボタンのクリック イベントで次のように修正されました。

private void btnCancel_Click(object sender, EventArgs e)
{
    // Stop the validation of any controls so the form can close.
    AutoValidate = AutoValidate.Disable;
    Close();
}
于 2012-09-27T13:13:30.423 に答える
19

CausesValidation[キャンセル] ボタンのプロパティを に設定しますfalse

于 2009-12-10T17:17:16.340 に答える
4

これらの回答はどれもうまくいきませんでしたが、このスレッドの最後の回答はうまくいきました。基本的に、次のことを行う必要があります。

  1. [キャンセル] ボタン (ある場合) の .CausesValidation が false に設定されていることを確認します。
  2. この仮想メソッドをオーバーライドします。

    protected override bool ProcessDialogKey(Keys keyData) {
        if (keyData == Keys.Escape) {
            this.AutoValidate = AutoValidate.Disable;
            CancelButton.PerformClick();
            this.AutoValidate = AutoValidate.Inherit;
            return true;
        }
        return base.ProcessDialogKey(keyData);
    }
    

私は実際にこれに答えたわけではなく、実際に答えた 2 人の男を指摘しただけです。

于 2014-03-20T23:21:40.917 に答える
4

CausesValidationプロパティを に設定しますfalse

于 2009-12-10T17:17:50.270 に答える
2

編集ボックスの検証コードのすぐ上に次を追加します。

if (btnCancel.focused)
  {
     return;
  }

それはそれを行う必要があります。

于 2016-01-28T12:31:43.267 に答える
2

CausesValidation を false に設定することが重要ですが、これだけでは十分ではありません。ボタンの親で CausesValidation が true に設定されている場合でも、検証イベントが呼び出されます。私のケースの 1 つで、フォームのパネルにキャンセル ボタンがあったため、フォームだけでなくパネルにも CausesValidation = false を設定する必要がありました。最後に、すべてのフォームを通過するよりも簡単だったので、プログラムでこれを行いました...

Control control = cancelButton;

while(control != null)
{
   control.CausesValidation = false;
   control = control.Parent;
}
于 2010-04-13T15:58:40.710 に答える
2

プロパティの賢明な使用は、Control.CausesValidationあなたが望むものを達成するのに役立ちます.

于 2009-12-10T17:18:00.440 に答える
1

Daniel Schaffer の回答を補足して: 編集ボックスがフォーカスを失ったときに検証が発生した場合は、ボタンをアクティブにしてローカル検証をバイパスし、とにかく終了することを禁止できます。

public class UnselectableButton : Button
{
    public UnselectableButton()
    {
        this.SetStyle(ControlStyles.Selectable, false);
    }
}

または DevExpress を使用する場合:

this.simpleButtonCancel.AllowFocus = false;

これを行うと、キーボード エクスペリエンスが変わることに注意してください。タブはキャンセル ボタンにフォーカスしなくなります。

于 2013-01-24T03:55:10.303 に答える
0

検証を実行するかどうかを決定できるように、BackgroundWorker を使用して少し遅延させたい場合があります。フォームを閉じる際の検証を回避する例を次に示します。

    // The flag
    private bool _isClosing = false;

    // Action that avoids validation
    protected override void OnClosing(CancelEventArgs e) {
        _isClosing = true;
        base.OnClosing(e);
    }

    // Validated event handler
    private void txtControlToValidate_Validated(object sender, EventArgs e) {           
        _isClosing = false;
        var worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.RunWorkerAsync();
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    }

    // Do validation on complete so you'll remain on same thread
    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        if (!_isClosing)
            DoValidationHere();
    }

    // Give a delay, I'm not sure this is necessary cause I tried to remove the Thread.Sleep and it was still working fine. 
    void worker_DoWork(object sender, DoWorkEventArgs e) {
        Thread.Sleep(100);
    }
于 2014-08-25T04:24:00.833 に答える
-1

これは私にとってはうまくいきます。

private void btnCancelar_MouseMove(object sender, MouseEventArgs e)
{
    foreach (Control item in Form.ActiveForm.Controls)
    {
        item.CausesValidation = false;
    }
}
于 2015-05-26T03:29:42.580 に答える