Program.cs で次のコードを使用して、メイン フォームの前に表示されるログイン フォームがあります。
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += Unhandled;
frmLogin loginForm;
using (loginForm = new frmLogin())
{
if (loginForm.ShowDialog() == DialogResult.OK)
{
NRBQConsts.userName = loginForm.UserName;
NRBQConsts.pwd = loginForm.Password;
NRBQConsts.currentSiteNum = loginForm.SiteNumber;
}
else
{
Application.Exit(); // klang!
}
}
Application.Run(new frmMain());
}
static void Unhandled(object sender, UnhandledExceptionEventArgs exArgs)
{
ExceptionLoggingService.Instance.WriteLog(String.Format("From
application-wide exception handler: {0}", exArgs.ExceptionObject));
}
ユーザーが (ログインを試みるのではなく) [閉じる] ボタンを選択すると、ログイン フォームが閉じ、メイン フォームが表示されなくなり、アプリがシャットダウンされます。ユーザーが [OK] ボタンを選択すると、ログイン フォームが閉じ、メイン フォームが表示されます。
「閉じる」ボタンを選択すると、Gong Show 風の「クラッシュ」音でアプリがクラッシュします。ログ ファイルに次の例外メッセージがあります。
日付: 2009 年 4 月 9 日 8:57:51 PM メッセージ: frmLogin.buttonOK_Click に到達しました 日付: 2009 年 4 月 9 日 8:57:51 PM メッセージ: アプリケーション全体の例外ハンドラーから: System.NullReferenceException: NullReferenceException at NRBQ.frmLogin System.Windows.Forms.Button.OnClick(EventArgs e) で System.Windows.Forms.Control.OnClick(EventArgs e) で NRBQ.frmLogin.buttonOK_Click(オブジェクト送信者、EventArgs e) で .GetSiteNum()。 Forms.ButtonBase.WnProc(WM wm, Int32 wParam, Int32 lParam) で System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam) で Microsoft.AGL.Forms.EVL.EnterModalDialog(IntPtr hwnModal) でNRBQ.Program.Main() の System.Windows.Forms.Form.ShowDialog()
ログインフォームの関連コードは次のとおりです。
public partial class frmLogin : Form
{
public string UserName { get { return textBoxUsername.Text; } }
public string Password { get { return textBoxPwd.Text; } }
public string SiteNumber { get { return GetSiteNum(); } }
private string GetSiteNum()
{
String candidateSiteNum =
listBoxSitesWithFetchedData.SelectedItem.ToString();
if (String.IsNullOrEmpty(candidateSiteNum))
{
candidateSiteNum = "42"; // TODO: Remove before deploying
}
return candidateSiteNum;
}
public frmLogin()
{
InitializeComponent();
}
private void buttonClose_Click(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmLogin.buttonClose_Click");
}
private void buttonOK_Click(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmLogin.buttonOK_Click");
if (SanityCheck())
{
this.Close(); // closing this login form should make the main
form active/visible
}
else
{
MessageBox.Show("You have not yet provided some key data; be
sure to enter a username and a password");
}
}
private bool SanityCheck()
{
// For now, anyway, no site has to be selected; if none, use "42" by
default
return ((!(String.IsNullOrEmpty(textBoxUsername.Text.Trim())))
&& (!(String.IsNullOrEmpty(textBoxPwd.Text.Trim()))));
}
注: 「OK」ボタンの DialogResult は「OK」に設定されています。「閉じる」ボタンの DialogResult は「キャンセル」に設定されています
Application.Exit() によってアプリがクラッシュするのはなぜですか? アプリを終了するためのより親切で穏やかな方法は何ですか?
また、[OK] ボタンを選択すると、その後メイン フォームが表示されないのはなぜですか? [OK] ボタンを選択しても (サニティ チェックに合格した場合)、ログイン フォームは閉じますが、それだけです... メイン フォームは表示されません。
アップデート
以下の回答に基づいてコードを修正したところ、キャンセルが正常に機能するようになりました (klang/crash なしでアプリを閉じます) が、ログイン フォームで [OK] ボタンを選択した後もメイン フォームが表示されません。ログインフォームコードでDialogResultをプログラムでOKに設定していますが。
以下の関連コード。
プログラム.CS
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += Unhandled;
frmLogin loginForm;
using (loginForm = new frmLogin())
{
if (loginForm.ShowDialog() == DialogResult.OK)
{
HHSConsts.userName = loginForm.UserName;
HHSConsts.pwd = loginForm.Password;
HHSConsts.currentSiteNum = loginForm.SiteNumber;
// TODO: Verify that these vals are valid
Application.Run(new frmMain());
}
}
}
FRMLOGIN.CS
private void buttonClose_Click(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmLogin.buttonClose_Click");
this.DialogResult = DialogResult.Cancel; // <= necessary?
this.Close();
}
private void buttonOK_Click(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmLogin.buttonOK_Click");
this.DialogResult = DialogResult.OK;
if (SanityCheck())
{
this.Close();
}
else
{
MessageBox.Show("You have not yet provided some key data; be
sure to enter a username and a password");
}
}
これは私のログファイルに表示されるものです:
日付: 2009 年 4 月 9 日 9:56:47 PM メッセージ: frmLogin.buttonOK_Click に到達しました 日付: 2009 年 4 月 9 日 9:56:48 PM メッセージ: アプリケーション全体の例外ハンドラーから: System.NullReferenceException: NullReferenceException at HHS.frmLogin .GetSiteNum() HHS.frmLogin.get_SiteNumber() で HHS.Program.Main()
マール・ハガードが歌ったように、「だから今戻ってきた、再びコードルームに...」
更新 2
GetSiteNum() にメッセージ ボックスを追加しました。
private string GetSiteNum()
{
ExceptionLoggingService.Instance.WriteLog("Reached
frmLogin.GetSiteNum()");
String candidateSiteNum =
listBoxSitesWithFetchedData.SelectedItem.ToString();
// TODO: Remove after testing
MessageBox.Show(String.Format("candidateSiteNum = {0}",
candidateSiteNum));
if (String.IsNullOrEmpty(candidateSiteNum))
{
candidateSiteNum = "03"; // TODO: Remove before deploying
}
return candidateSiteNum;
}
...そして、私はそれを見ないので、爆発しています:
String candidateSiteNum = listBoxSitesWithFetchedData.SelectedItem.ToString();
...このログイン フォームで [OK] ボタンを選択した直後。