DOBON.NET DOBON.NETプログラミング掲示板過去ログ

例外発生時にMaskedTextBoxにフォーカスを移し、全選択状態にする方法

環境/言語:[.NET Framework2.0/C#/Windwosアプリケーション]
分類:[.NET]



例外発生時にMaskedTextBoxにフォーカスを移し、全選択状態にする方法

こんにちは。アべです。

入力エラーを例外として扱っております。
(エラーのキャッチは、ApplicationクラスのThreadExceptionメソッドを
使用して一箇所で行っています。)

入力エラーの例外をキャッチし、対象のコントロールに
フォーカスを移し、全選択状態にするということで、
MaskedTextBoxだと出来ないのですが、何か考え方が
間違っているのでしょうか?

原因がわからず非常に困っております。
どなたかエラー発生時に全選択状態にする方法がわかれば
アドバイスをお願い致します。

↓再現ソース
Enterキーを押すと例外が発生し、そのコントロールにフォーカスを移し、
全選択状態にする処理が入っているのですが、それが正常に動作しません。

▼Program.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsApplication1
{
static class Program
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
_f = new Form1();
Application.Run(_f);
}

static Form1 _f;

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
if (e.Exception is ApplicationException)
{
if (e.Exception.Message == "a")
{
_f.textBox1.Focus();
_f.textBox1.SelectAll();
}
else if (e.Exception.Message == "b")
{
_f.maskedTextBox1.Focus();
_f.maskedTextBox1.SelectAll();
}
}

}
}
}
▼Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}


private void maskedTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
throw new ApplicationException("b");
}
}

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
throw new ApplicationException("a");
}
}
}
}
▼Form1.Designer.cs
namespace WindowsApplication1
{
partial class Form1
{
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
/// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows フォーム デザイナで生成されたコード

/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
private void InitializeComponent()
{
this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// maskedTextBox1
//
this.maskedTextBox1.Location = new System.Drawing.Point(44, 27);
this.maskedTextBox1.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5);
this.maskedTextBox1.Mask = "0000/00/00";
this.maskedTextBox1.Name = "maskedTextBox1";
this.maskedTextBox1.Size = new System.Drawing.Size(180, 28);
this.maskedTextBox1.TabIndex = 1;
this.maskedTextBox1.ValidatingType = typeof(System.DateTime);
this.maskedTextBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.maskedTextBox1_KeyDown);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(44, 63);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(180, 28);
this.textBox1.TabIndex = 4;
this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(321, 160);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.maskedTextBox1);
this.Font = new System.Drawing.Font("MS ゴシック", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
this.Margin = new System.Windows.Forms.Padding(6, 5, 6, 5);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

//internal AMaskedTextBox maskedTextBox1;
internal System.Windows.Forms.MaskedTextBox maskedTextBox1;
internal System.Windows.Forms.TextBox textBox1;
}
}

以上
■No17928に返信(kiyo7447さんの記事)
> 入力エラーを例外として扱っております。
> (エラーのキャッチは、ApplicationクラスのThreadExceptionメソッドを
> 使用して一箇所で行っています。)

これにまず反対です。
エラー検証で NG だった場合は「例外」ではないでしょう。
想定の範囲内ってやつでしょう。
アドバイスを有難うございます。

例外の考え方でこちらは、
入力エラーから環境エラーの想定内(入力エラーからネットワークエラーやデッドロック)
から外も含めて全て一箇所でキャッチ行っており、この仕組みを変えることが
簡単には出来ませんので、この問題の原因をクリアしなければなりません。

お手数ですが、引き続きどなたかわかる方アドバイスをお願いします。

簡単に変えることは出来ないとは、
入力エラーお発生時は
throw new InputException("○○が日付ではありません。正しい日付を入力して下さい。", _dateNyukin);
として1行のみコードを記述しており、
これを
1.メッセージボックスを使ってエラー表示
2.該当のコントロール(_dateNyuukin)にフォーカス制御
3.該当のコントロール(_dateNyuukin)の全選択状態へ変更
4.このチェックでエラーがあったので、次のコントロールは
エラーチェックしないように制御を入れる。(戻り値を使った制御?)
とすることが非常に手間です。

以上
2006/10/18(Wed) 10:14:23 編集(投稿者)

■No17928に返信(kiyo7447さんの記事)

こんにちは エツです。

すでに試されているとは思いますが、フォームにMaskedTextBoxとbuttonを貼り付けて簡単なテストフォームをつくり
buttonをクリックするとMaskedTextBoxは全選択されます。

private void button1_Click(object sender, EventArgs e)
{
maskedTextBox1.SelectAll(); //この順序が逆でもOK
maskedTextBox1.Focus();
}

ですから
>MaskedTextBoxだと出来ないのですが .....

は違うと思います。

#フォームを立ち上げたときにTextBoxは全選択、MaskedTextBoxは全選択されない の違いはあります。
これが関係しているのでしょうか?

Maskプロパティを特に設定しないと、手元(VS2005/C#)で全選択できてます。ただ、確かにMaskプロパティを"0000/00/00"にするとダメですね。Why?

なんとなくApplication_ThreadExceptionが呼ばれてないっぽかったので、試しに
>_f.maskedTextBox1.Focus();
>_f.maskedTextBox1.SelectAll();
の直前にMessageBox.Show()を入れたところ、なんか全選択できちゃったりするのですが。。。MessageBox外すとダメ。私には理解不能です、ごめんなさい。
2006/10/18(Wed) 11:53:02 編集(投稿者)
2006/10/18(Wed) 11:52:26 編集(投稿者)

エツさん、あきひろさん
回答を有難うございます。

エツさんの言われるとおり、MaskedTextBoxは全選択されるコンポーネントで
あるので、やり方は間違っていないと思っています。

しかし、あきひろさんが見つけたMessageBox.Show()を
はさむと動くということは、、、、!?、!!

閃きました。対処療法ですが、

Application.DoEvents(); ←これを入れて対応しました。
_f.maskedTextBox1.Focus();
_f.maskedTextBox1.SelectAll();

DoEventsで対応しました。

原因は引き続き、気づいたら情報を求めるとして、とりあえずはこの実装で進めて見たいと思います。
有難うございました。
解決済み!
■No17937に返信(kiyo7447さんの記事)

あきひろさんのかきこみ
>ただ、確かにMaskプロパティを"0000/00/00"にするとダメですね。
もう少し調べてみました。

次のようにすると上手くいきました。

private void button1_Click(object sender, EventArgs e)
{
maskedTextBox1.Focus();
}

private void maskedTextBox1_Enter(object sender, EventArgs e)
{
maskedTextBox1.SelectAll();
}


解決したとの事ですが宜しければ参考にして下さい。


>原因は引き続き、気づいたら情報を求めるとして、とりあえずはこの実装で進めて見たいと思います。
>有難うございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板