<class>.ShowDialog()
で表示するダイアログがあります。 [OK]ボタンと[キャンセル]ボタンがあります。 [OK]ボタンにはイベントハンドラもあります。
イベントハンドラーで入力の検証を行い、失敗した場合はメッセージボックスでユーザーに通知し、ダイアログが閉じないようにします。最後の部分を実行する方法がわかりません(終了を防止します)。
ポップエラーダイアログが必要だと指定した場合、これを行う方法の1つは検証を OnClosing
イベントハンドラーに移動します。この例では、ユーザーがダイアログの質問にyesと答えた場合、フォームのクローズは中止されます。
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// Determine if text has changed in the textbox by comparing to original text.
if (textBox1.Text != strMyOriginalText)
{
// Display a MsgBox asking the user to save changes or abort.
if(MessageBox.Show("Do you want to save changes to your text?", "My Application",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// Cancel the Closing event from closing the form.
e.Cancel = true;
// Call method to save file...
}
}
}
設定することにより e.Cancel = true
フォームが閉じないようにします。
ただし、検証エラーをインラインで表示する方がデザイン/ユーザーエクスペリエンスの向上につながります(何らかの方法で問題のあるフィールドを強調表示したり、ツールチップを表示したりするなど) )、ユーザーが最初に[OK]ボタンを選択できないようにします。
フォームのDialogResult
をDialogResult.None
に設定することにより、クローズをキャンセルできます。
Button1がAcceptButtonである例:
private void button1_Click(object sender, EventArgs e) {
if (!validate())
this.DialogResult = DialogResult.None;
}
ユーザーがbutton1をクリックし、validateメソッドがfalseを返すと、フォームは閉じられません。
これにはFormClosingイベントを使用しないでください。キャンセルまたはXをクリックしてダイアログを閉じることができます。OKボタンのClickイベントハンドラーを実装し、満足するまで閉じないでください。
private void btnOk_Click(object sender, EventArgs e) {
if (ValidateControls())
this.DialogResult = DialogResult.OK;
}
ここで、「ValidateControls」は検証ロジックです。何か問題がある場合はfalseを返します。
このコードを使用してください:
private void btnOk_Click(object sender, EventArgs e) {
if (ValidateControls())
this.DialogResult = DialogResult.OK;
}
問題は、ユーザーがフォームを閉じるためにボタンを2回クリックする必要があることです。
これはあなたの質問に直接答えるものではありません(他の人はすでに持っています)が、使いやすさの観点から、入力が無効な間は問題のあるボタンを無効にすることをお勧めします。
FormClosingをキャッチして、フォームを開いたままにすることができます。そのためには、イベント引数オブジェクトのCancelプロパティを使用します。
e.Cancel = true;
フォームが閉じないようにする必要があります。
void SaveInfo()
{
blnCanCloseForm = false;
Vosol[] vs = getAdd2DBVosol();
if (DGError.RowCount > 0)
return;
Thread myThread = new Thread(() =>
{
this.Invoke((MethodInvoker)delegate {
picLoad.Visible = true;
lblProcces.Text = "Saving ...";
});
int intError = setAdd2DBVsosol(vs);
Action action = (() =>
{
if (intError > 0)
{
objVosolError = objVosolError.Where(c => c != null).ToArray();
DGError.DataSource = objVosolError;// dtErrorDup.DefaultView;
DGError.Refresh();
DGError.Show();
lblMSG.Text = "Check Errors...";
}
else
{
MessageBox.Show("Saved All Records...");
blnCanCloseForm = true;
this.DialogResult = DialogResult.OK;
this.Close();
}
});
this.Invoke((MethodInvoker)delegate {
picLoad.Visible = false;
lblProcces.Text = "";
});
this.BeginInvoke(action);
});
myThread.Start();
}
void frmExcellImportInfo_FormClosing(object s, FormClosingEventArgs e)
{
if (!blnCanCloseForm)
e.Cancel = true;
}
イベント関数に1行追加するだけです
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
this->DialogResult = System::Windows::Forms::DialogResult::None;
}
より良い例を見つける時間があればいいのですが、既存のWindowsフォーム検証テクニックを使用してこれを行う方がはるかに良いでしょう。