- SADAS
- 会議室デビュー日: 2007/01/17
- 投稿数: 4
|
投稿日時: 2007-01-17 13:49
お世話になっています。初めて投稿します。
.NET2003 C#を使っています。
<実現したいこと>
○コントロール
・テキストボックスとボタンを配置します。
・ボタンにはショートカットを設定しています。(&P)
○動き
テキストボックスに値を入力し、ボタン押下時(クリックでもショートカットでも)に入力チェックを行いNGであればテキストボックスに戻る。
<現在のコード>
private void button1_Click(object sender, System.EventArgs e)
{
Console.WriteLine("{0}","button1_Click");
button1.Select();
}
private void textBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
Console.WriteLine("{0}:{1}","textBox1_Validating",ActiveControl.Name);
if(ActiveControl.Equals(sender)) return; //--------@
//検証する条件
if(textBox1.Text == "ERR")
{
e.Cancel = true;
}
}
<事象>
ボタンをクリックした時はうまく動くのですが、検証がエラーになる値をテキストに入力し、ショートカットでボタンを連続押下した時、想定した動きになりません。
ショートカットで押下1回目は以下のようになります。
textBox1_Validating:textBox1
button1_Click
textBox1_Validating:button1
ショートカットで押下2回目以降は以下のようになります。
textBox1_Validating:textBox1 ----2回目
textBox1_Validating:textBox1 ----3回目
textBox1_Validating:textBox1 ----4回目
2回目以降、ショートカットでボタンを押下してもテキストボックスのValidatingしか走らず、button1_Clickメソッドが実行されない為、検証ができない状態となり困っています。
@の条件は「×」押下時等で必要なので外せません。
なにか良い方法があればご教授願います。
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2007-01-17 15:06
引用: |
|
SADASさんの書き込み (2007-01-17 13:49) より:
ショートカットで押下2回目以降は以下のようになります。
textBox1_Validating:textBox1 ----2回目
textBox1_Validating:textBox1 ----3回目
textBox1_Validating:textBox1 ----4回目
|
これは、単純に button1 にフォーカスが移っているからではないでしょうか。
それと、Validating で検証中にフォーカスを動かすことはしない方が良いです。
予期しないことが起きます。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- SADAS
- 会議室デビュー日: 2007/01/17
- 投稿数: 4
|
投稿日時: 2007-01-17 16:30
引用: |
|
じゃんぬねっとさんの書き込み (2007-01-17 15:06) より:
これは、単純に button1 にフォーカスが移っているからではないでしょうか。
|
textBox1_ValidatingのConsole.WriteLineを以下に変更して試してみました。
Console.WriteLine("{0} : ActiveControl={1} : button1.Focused={2} : textBox1.Focused={3}","textBox1_Validating",ActiveControl.Name ,button1.Focused,textBox1.Focused);
ショートカット1回目
textBox1_Validating : ActiveControl=textBox1 : button1.Focused=False :
textBox1.Focused=True
button1_Click
textBox1_Validating : ActiveControl=button1 : button1.Focused=False :
textBox1.Focused=True
ショートカット2回目
textBox1_Validating : ActiveControl=textBox1 : button1.Focused=False :
textBox1.Focused=True
textBox1_Validating : ActiveControl=textBox1 : button1.Focused=False :
textBox1.Focused=True
この結果からするとbutton1 にフォーカスは移っていないと思われます。
宜しくお願いします。
|
- ぽぴ王子
- ぬし
- 会議室デビュー日: 2006/03/24
- 投稿数: 475
- お住まい・勤務地: お住まい:城・勤務地:城
|
投稿日時: 2007-01-17 17:17
まずは再現するミニマムコードと、再現する方法を提示してみると良いかと思います。
SADAS さんのコードをそのまま使用して動かしてみましたが、2回目以降も1回目と
同様の動きになりました。
で。
コード: |
|
//検証する条件
if(textBox1.Text == "ERR")
{
e.Cancel = true;
}
|
こんなところにあからさまに怪しいコードがあるのですが、ここを通っているために
textBox1_Validating から抜け出せていなかったりしませんか?
どこか(この場合は button1_Click あたり)で textBox1.Text = "ERR" のよう
な処理が入っていませんか?ということです。
(実際、そのようなコードを入れたら SADAS さんのおっしゃる現象が再現しました)
そのあたりをよく調べてみてください(本当は他人に見せる前に検証しておくべきか
もしれませんけどね)。
_________________ ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
|
- SADAS
- 会議室デビュー日: 2007/01/17
- 投稿数: 4
|
投稿日時: 2007-01-17 17:48
引用: |
|
ぽぴ王子さんの書き込み (2007-01-17 17:17) より:
まずは再現するミニマムコードと、再現する方法を提示してみると良いかと思います。
SADAS さんのコードをそのまま使用して動かしてみましたが、2回目以降も1回目と
同様の動きになりました。
で。
|
長くなりますが、以下にコードを書きます。
ただ基本的には、ぽぴ王子さんが試されたのと同じです。
コード: |
|
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace ボタンのショートカット
{
/// <summary>
/// Form1 の概要の説明です。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows フォーム デザイナ サポートに必要です。
//
InitializeComponent();
//
// TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
//
}
/// <summary>
/// 使用されているリソースに後処理を実行します。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows フォーム デザイナで生成されたコード
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(32, 24);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
this.textBox1.Validating += new System.ComponentModel.CancelEventHandler(this.textBox1_Validating);
//
// button1
//
this.button1.Location = new System.Drawing.Point(32, 80);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "&button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(144, 80);
this.button2.Name = "button2";
this.button2.TabIndex = 2;
this.button2.Text = "閉じる";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
this.ClientSize = new System.Drawing.Size(248, 157);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button2_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void button1_Click(object sender, System.EventArgs e)
{
Console.WriteLine("{0}","button1_Click");
button1.Select();
}
private void textBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
Console.WriteLine("{0} : ActiveControl={1} : button1.Focused={2} : textBox1.Focused={3}","textBox1_Validating",ActiveControl.Name
,button1.Focused,textBox1.Focused);
if(ActiveControl.Equals(sender)) return;
if(textBox1.Text == "ERR")
{
MessageBox.Show("ERR");
e.Cancel = true;
}
}
}
}
|
再現方法
@テキストボックスに "ERR" と入力します。
Aテキストボックスにカーソルがある状態で「Alt + B」でbutton1を押下します。
Bメッセージボックス"ERR"が表示されて、テキストボックスにカーソルが戻ります。
C再度「Alt + B」でbutton1を押下します。
Dメッセージボックス"ERR"は表示されず、テキストボックスにカーソルがある状態のままです。
Eさらにこの状態で、テキストボックスに"ERR"以外(例"OK")を入力し、「Alt + B」でbutton1を押下しても、button1にカーソルが移動しません。
※本画面を起動直後であれば"ERR"以外(例"OK")を入力した場合、「Alt + B」でbutton1にカーソルが移動します。
以上です。宜しくお願いします。
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2007-01-17 18:29
引用: |
|
SADASさんの書き込み (2007-01-17 13:49) より:
button1.Select();
|
とりあえず、この 2 箇所が、諸悪の根源です。
Validating で検証中にフォーカスを動かすことはしない方が良いです。
(キャンセル時、または、アラートボックスが表示された場合) 予期しないことが起きます。
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- ぽぴ王子
- ぬし
- 会議室デビュー日: 2006/03/24
- 投稿数: 475
- お住まい・勤務地: お住まい:城・勤務地:城
|
投稿日時: 2007-01-17 18:53
コードと再現方法の提示どうもありがとうございます。
私も少しテストしてみました。
…っと、この後にいろいろ書いていましたが、じゃんぬねっとさんがおっしゃられていることで
全て完結してしまいました ○| ̄|_
前回の私のテストでは
if(ActiveControl.Equals(sender)) return;
を入れていなかったために少し結果に狂いが生じていたようです。すいません。
どちらにしても、button1.Select(); はマズいように思えますね。
上記のコード( ActiveControl をチェックする方法)もいろいろと問題を含んでいるよ
うな気がするので、個人的にはオススメできません。
2回目以降は ActiveControl == textBox1 になるので、エラーチェック自体が処
理されません。
_________________ ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
|
- SADAS
- 会議室デビュー日: 2007/01/17
- 投稿数: 4
|
投稿日時: 2007-01-17 19:35
引用: |
|
じゃんぬねっとさんの書き込み (2007-01-17 18:29) より:
とりあえず、この 2 箇所が、諸悪の根源です。
Validating で検証中にフォーカスを動かすことはしない方が良いです。
|
引用: |
|
ぽぴ王子さんの書き込み (2007-01-17 18:53) より:
どちらにしても、button1.Select(); はマズいように思えますね。
|
じゃんぬねっとさん、ぽぴ王子さん、何度もすみません。
Validating で検証中にフォーカス移動するコードがまずいというのは分かりました。
という事は、ショートカットでボタン押下した後、テキストボックスの検証でOKだった場合にボタンにフォーカスを移動させたかったのですが、できない(しないほうがよい?)のでしょうか?
引用: |
|
ぽぴ王子さんの書き込み (2007-01-17 18:53) より:
上記のコード( ActiveControl をチェックする方法)もいろいろと問題を含んでいるよ
うな気がするので、個人的にはオススメできません。
|
いまValidatingを使用するとき、ActiveControl でチェックしているのですが、もしよろしければお勧めの方法を教えて頂きたいのですが。
宜しくお願いします。
|