- PR -

KeyDown、Clickイベント発生コントロールの特定方法について

1
投稿者投稿内容
ごんた
会議室デビュー日: 2005/06/27
投稿数: 18
投稿日時: 2005-10-25 11:01
どなたか知恵をお貸し下さい。

初めに、Formを継承したオリジナルのFormクラスを作成し、更にそのクラスを
継承して複数の画面を作ったとします。

各画面では、それぞれFUNCTIONボタンに紐づいたボタンを所持し、
そのFUNCTIONボタンにて、DBへの登録や画面を閉じたりする動作を行います。
※ちなみに、操作上TABやEnterでは上記FUNCTIONボタンに遷移させたくない為、
各FUNCTIONボタンのTabStopプロパティはfalseに設定。

また、各画面ではFUNCTIONボタン以外にもそれぞれコントロールを配置しており
(但し、ボタンコントロールはFUNCTIONボタン以外に配置していない)、

その中のTextBoxでは、Validationイベント発生時に共通の文字チェック等
行っているのですが、
訳あってFUNCTIONボタンのCausesValidationプロパティをfalseにしている為、
TextBoxからいきなりFUNCTIONボタン押下(又はそれに紐付くボタンをClick)した
場合に、TextBoxのValidationイベントが発生しません。

(ココから本題)
そこで、各画面の基底となっている前述のオリジナルのFormクラスにて、
KeyPreviewプロパティをtrueに設定して、KeyDownイベントやClickイベントを拾い、
そのイベント処理の中で、
KeyDownやClickを発生させたコントロールがボタンである場合は、
各TextBoxの文字列チェックを行わせる様にしたいのですが、
「KeyDownやClickを発生させたコントロールがボタンである」という
特定が出来ません。
senderや、KeyEventArgs・EventArgsからGetType()でイベントの発生主を調べても、
各画面のクラス名になってしまいます。

上物の画面数が多い為、出来る限り基底のFormクラスで処理させたく、
基底のFormクラス側で(上記条件で)
前述の「KeyDownやClickを発生させたコントロールがボタンである」という
特定は可能なのでしょうか?

どなたかご存知であれば、アドバイスお願い致します。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-25 11:16
引用:

ごんたさんの書き込み (2005-10-25 11:01) より:

KeyDownやClickを発生させたコントロールがボタンである場合は、
各TextBoxの文字列チェックを行わせる様にしたいのですが、
「KeyDownやClickを発生させたコントロールがボタンである」という
特定が出来ません。
senderや、KeyEventArgs・EventArgsからGetType()でイベントの発生主を調べても、
各画面のクラス名になってしまいます。


sender でそのまま比較すれば良いと思いますが...
どうやったら、各画面のクラス名になったのでしょうか...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
たつごろー
ぬし
会議室デビュー日: 2004/10/25
投稿数: 496
投稿日時: 2005-10-25 11:22
私がなにか問題にぶちあたったときは、現象の出る最小限のコードを作成することが解決の第一歩になることが多いです。
特定の問題だとお思いのようでしたら、まずはおためしください。
ここに書いていただければ、どういうことで困っているかも判りやすいですし。

_________________
たつごろー
codeseek
こみゅぷらす
ごんた
会議室デビュー日: 2005/06/27
投稿数: 18
投稿日時: 2005-10-25 11:35
to じゃんぬねっと様

 早速のコメントありがとうございます。

 >sender でそのまま比較すれば良いと思いますが...
 >どうやったら、各画面のクラス名になったのでしょうか...

 「sender.GetType().FullName.ToString()」で文字列取得したら、
 各画面のクラス名が取得されました。。。
 希望としては、System.Windows.Forms.Buttonを取得したかったのですが。
 ”senderでそのまま比較”とは、どういったやり方でしょうか?

to たつごろー様

 アドバイスありがとうございます。

 困っている事というのは、上記のじゃんぬねっと様への返答で書いた通りです。。。
 (最小限のコードについては、現在当方で作成中です。)

以上です。

よろしくお願い致します。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-25 11:41
根本的な悩みの方を答えてませんでした。

引用:

ごんたさんの書き込み (2005-10-25 11:01) より:

訳あってFUNCTIONボタンのCausesValidationプロパティをfalseにしている為、
TextBoxからいきなりFUNCTIONボタン押下(又はそれに紐付くボタンをClick)した
場合に、TextBoxのValidationイベントが発生しません。


私の場合、エラー検証に関しては、別で静的メソッドを実装して行っています。
値さえ受け取れば、後はビジネス ロジックですからね。

画面の値を渡して結果を bool 値で返して、
Validating イベントでの Cancel の値を決めるわけです。
こうしておけば、いわゆる [実行] ボタンでの検証も同じメソッドを呼ぶだけで事足ります。

---
以下についてはお勧めしません。

Validating イベントを意図的に起こすのであれば、
Function と謡ってるショートカットのドリブン部分で、
OnValidating みたいなメソッドを呼び出して起こす方法もあるでしょう。
(カスタム コントロールになりますが)

また、Form.ActiveControl に null 値を入れて Validating イベントを起こすちょっと異質な方法もあります。

いずれにせよ、イベントは内部で起きるものであって、
"意図的に" 外部から起こすものではないのでお勧めはしません。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ごんた
会議室デビュー日: 2005/06/27
投稿数: 18
投稿日時: 2005-10-25 11:55
to じゃんぬねっと様

>私の場合、エラー検証に関しては、別で静的メソッドを実装して行っています。
>値さえ受け取れば、後はビジネス ロジックですからね。

>画面の値を渡して結果を bool 値で返して、
>Validating イベントでの Cancel の値を決めるわけです。
>こうしておけば、いわゆる [実行] ボタンでの検証も同じメソッドを呼ぶだけで事足>ります。

説明が不足して申し訳ありません。
実は自分も検証用の静的メソッドを作っており、TextBox(これもTextBoxを継承した
自作のTextBoxクラス)のValidatingイベント処理メソッドにて使用しています。

但し、FUNCTIONボタン押下時はValidatingイベントが発生しないので、各画面にて
前述の検証用メソッドを呼びたいトコロなのですが、
画面数が多い為出来るだけそれもせずに、画面の基底のFormクラスで実現したかった
という訳です。
それで、基底のFormクラスでKeyDownやClickを拾ってFUNCTIONボタン押下を認識
しようとしたのですが。。。

>Validating イベントを意図的に起こすのであれば、
>Function と謡ってるショートカットのドリブン部分で、
>OnValidating みたいなメソッドを呼び出して起こす方法もあるでしょう。
>(カスタム コントロールになりますが)

>また、Form.ActiveControl に null 値を入れて Validating イベントを起こすちょっ>と異質な方法もあります。

ありがとうございます。
最終的にはもしかしたらやってみるかもしれません。

以上です。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-25 11:58
引用:

ごんたさんの書き込み (2005-10-25 11:35) より:

希望としては、System.Windows.Forms.Buttonを取得したかったのですが。
”senderでそのまま比較”とは、どういったやり方でしょうか?


ところで、お使いの言語は何でしょうか?
C# ですか? VB ですか? (J# または C++.NET でないことは、ソースから見て判りますが)
C# なら is で、VB なら TypeOf 〜 Is を使います。

その前に Function から Button を仮想的に押下させる方法はどうやってるのでしょうか?
PerformClick メソッドを使っているにしても、OnClick メソッドを使っているにしても、
sender には System.Windows.Forms.Button しか入りようがないです。

"今" どの Type のコントロールにいるのかが判れば、
Function からの実行なのかを判断できるのではないでしょうか?
つまり、Form.ActiveControl で判断すべきことなのではないでしょうか?

コード:

    [C#1.0 (2003)]
    private void button1_Click(object sender, System.EventArgs e) {
        if (this.ActiveControl is System.Windows.Forms.Button) {
            MessageBox.Show("ボタンが Active なのでボタンを押下したと見なす");
        } else {
            MessageBox.Show("ボタン以外から実行されたと見なす");
        }
    }


コード:

    [VB7 (2003)]
    Private Sub Button1_Click(...) Handles Button1.Click
        If TypeOf Me.ActiveControl Is System.Windows.Forms.Button Then
            MessageBox.Show("ボタンが Active なのでボタンを押下したと見なす")
        Else
            MessageBox.Show("ボタン以外から実行されたと見なす")
        End If
    End Sub


Button 上でも、Function が有効であるのならば判断できません。
(ただし、コントロール決めうちすれば判断はできますね)

どちらにしても、型を見て動的に... という仕様は好きではないです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-10-26 21:43
引用:

ごんたさんの書き込み (2005-10-25 11:01) より:

(ココから本題)
そこで、各画面の基底となっている前述のオリジナルのFormクラスにて、
KeyPreviewプロパティをtrueに設定して、KeyDownイベントやClickイベントを拾い、
そのイベント処理の中で、

KeyDownやClickを発生させたコントロールがボタンである場合は、
各TextBoxの文字列チェックを行わせる様にしたいのですが、
「KeyDownやClickを発生させたコントロールがボタンである」という
特定が出来ません。
senderや、KeyEventArgs・EventArgsからGetType()でイベントの発生主を調べても、
各画面のクラス名になってしまいます。


KeyPreview で、フォームがすべて受け取って、その中で判断しようとしたら、そりゃ、フォームがセンダーになる罠。
___________________________________________________________________
□ written by Jitta on 2005/10/262005/10/26
□ Microsoft MVP :Visual Developer ASP/ASP.NET Oct.2004-Sept.2006
_________________
1

スキルアップ/キャリアアップ(JOB@IT)