C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: ユーザコントロール内でのキーイベント無効


(過去ログ 30 を表示中)

[トピック内 15 記事 (1 - 15 表示)]  << 0 >>

■14294 / inTopicNo.1)  ユーザコントロール内でのキーイベント無効
  
□投稿者/ taguchi (15回)-(2008/02/14(Thu) 19:53:11)

分類:[C#] 

度々恐れ入ります。

ユーザコントロール内にTextboxを配置し、
イベントハンドラで実装したメソッドでは、
そのTextBoxで押下されたキーを条件判断により無効とするように
しているのですが、無効になってくれません。

public partial class Hoge : UserControl 
{
    public event System.EventHandler HogeEvents;

                         :
                         略
                         :

    private void HogeTextBox_KeyDown(object sender, KeyEventArgs e)
    {

        <該当条件>

                e.Handled = true;
                this.HogeEvents(sender, e);
                break;
                         :
                         :

イベントハンドラを実装した場合、
e.Handled = true;でキャンセルできないのでしょうか?

アドバイスありましたら、宜しくお願い致します。

引用返信 編集キー/
■14306 / inTopicNo.2)  Re[1]: ユーザコントロール内でのキーイベント無効
□投稿者/ ダッチ (192回)-(2008/02/14(Thu) 22:17:43)
taguchi さん、こんにちは
ダッチです。

e.SuppressKeyPress プロパティに True を設定してみてください。
TextBox に入力した文字が表示されなくなると思います。

あくまでキーボードから入力した文字が表示されなくなるだけで
マウスで貼り付けなどをした場合は表示されます。
引用返信 編集キー/
■14308 / inTopicNo.3)  Re[2]: ユーザコントロール内でのキーイベント無効
□投稿者/ taguchi (16回)-(2008/02/14(Thu) 22:30:09)
ダッチさん
アドバイス有難う御座いました。

> e.SuppressKeyPress プロパティに True を設定してみてください。
> TextBox に入力した文字が表示されなくなると思います。

試してみた所、変化無しでした・・・。

e.Handled = true;
e.SuppressKeyPress = true;
this.HogeEvents(sender, e);
break;

コーディング順序が悪いのかと、色々試してみたのですが、駄目でした。
何かコーディング自体が悪いのでしょうか?

何かアドバイスありましたら、宜しくお願いします。
引用返信 編集キー/
■14312 / inTopicNo.4)  Re[3]: ユーザコントロール内でのキーイベント無効
□投稿者/ ダッチ (193回)-(2008/02/14(Thu) 22:54:14)
> コーディング順序が悪いのかと、色々試してみたのですが、駄目でした。
> 何かコーディング自体が悪いのでしょうか?

確認ですがそのイベントハンドラには処理が来ていますでしょうか。
ブレークポイントを置いて確認してみてください。
該当条件といわれている処理からもれている可能性もあると思います。

またこちらの処理が影響しているということはありませんでしょうか。
this.HogeEvents(sender, e);

もし不安だったら新規に TextBox を配置して、その KeyDown イベントで
e.SuppressKeyPress = true;
としてみてください。

引用返信 編集キー/
■14313 / inTopicNo.5)  Re[3]: ユーザコントロール内でのキーイベント無効
□投稿者/ 魔界の仮面弁士 (625回)-(2008/02/14(Thu) 22:58:43)
No14308 (taguchi さん) に返信
> e.Handled = true;
> e.SuppressKeyPress = true;
> this.HogeEvents(sender, e);
> break;
そもそも HogeEvents は、何を目的としたイベントなのでしょうか?

コードを見る限りでは、利用側がイベントを実装しようと実装せずとも、
TextBox の KeyDown 処理には何の影響も与えるようには見えないのですが…。
(となると、おかしいのは省略されている部分?)


> 何かコーディング自体が悪いのでしょうか?
コードが大きく省略されているので判断が難しいですが、ざっと見ておかしいのは:

(1) HogeEvents の第二引数に、KeyEventArgs を渡している。
 → 間違いではありませんが、ちょっと奇妙に見えました。
  KeyEventArgs を渡すつもりなら、イベント定義もそれに合わせるべきですし、
  EventArgs で十分なのであれば、e ではなく、EventArgs.Empty を渡すべきかと。

(2) this.HogeEvents の null チェックをせずに Invoke している。
引用返信 編集キー/
■14315 / inTopicNo.6)  Re[4]: ユーザコントロール内でのキーイベント無効
□投稿者/ taguchi (17回)-(2008/02/15(Fri) 00:00:41)
2008/02/15(Fri) 00:00:57 編集(投稿者)
ダッチさん
アドバイスありがとうございます。

> 確認ですがそのイベントハンドラには処理が来ていますでしょうか。
目視できる処理が動いてますので、
問題ないと考えております。

> またこちらの処理が影響しているということはありませんでしょうか。
> this.HogeEvents(sender, e);

MessageBox.show程度の事を行っておりますが、
画面遷移で何か、原因があるのでしょうか。

> もし不安だったら新規に TextBox を配置して、その KeyDown イベントで
> e.SuppressKeyPress = true;
> としてみてください。

新規に必要なイベントのみ記述したコントロールを作ってみました。

   public partial class UserControl1 : UserControl
    {
        public event System.EventHandler HogeEvents;

        public UserControl1()
        {
            InitializeComponent();
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.A:
                    if (this.HogeEvents== null)
                        break;

                    this.HogeEvents(sender, e);
                    e.SuppressKeyPress = true;
                    e.Handled = true;
                    break;
            }
        }
    }

やはり、これでも文字をキャンセルする事が出来ませんでした。
何か、アドバイスありましたら、よろしくお願いいたします。

引用返信 編集キー/
■14316 / inTopicNo.7)  Re[5]: ユーザコントロール内でのキーイベント無効
□投稿者/ taguchi (18回)-(2008/02/15(Fri) 00:01:43)
2008/02/15(Fri) 00:03:33 編集(投稿者)

<pre><pre>魔界の仮面弁士さん
いつもありがとうございます。

> そもそも HogeEvents は、何を目的としたイベントなのでしょうか?

あるキー(A)が押下された場合、そのキーを入力する事無く、
利用側にイベントとして通知し、その先は利用側が処理を行うと言うものです。
ですので、そのキーが押下された場合無視せねばなりません。
現在の状況では、イベントは発生しますが、その押下された文字はテキストボックスに
入力されてしまいます。

> コードを見る限りでは、利用側がイベントを実装しようと実装せずとも、
> TextBox の KeyDown 処理には何の影響も与えるようには見えないのですが…。
> (となると、おかしいのは省略されている部分?)

省略しすぎて申し訳ありません。
別段たいした処理もしておりません。
Enter、Leaveイベントで、そのテキストボックスに対して、文字操作を行っている位です。

private void HogeTextBox1_Enter(object sender, EventArgs e)
{
if (this.TextBox1.Text.Equals("B"))
this.TextBox1.Text = "C";
}

private void HogeTextBox_Leave(object sender, EventArgs e)
{
if (this.TextBox1.Text.Trim().Equals(""))
this.TextBox1.Text = "D";
}

> (1) HogeEvents の第二引数に、KeyEventArgs を渡している。
>  → 間違いではありませんが、ちょっと奇妙に見えました。
>   KeyEventArgs を渡すつもりなら、イベント定義もそれに合わせるべきですし、
>   EventArgs で十分なのであれば、e ではなく、EventArgs.Empty を渡すべきかと。

TextBox1で発生したイベント内容をそのまま引き渡したかっただけなのですが、
意味の無い事になっていますでしょうか。

> (2) this.HogeEvents の null チェックをせずに Invoke している。

一応、イベントのインスタンスが掛かっているかのチェックを行って
処理が実行されるようにしております。

if (this.HogeEvents == null)
break;

e.Handled = true;
e.SuppressKeyPress = true;
this.HogeEvents(sender, e);
break;

大変お手数ですが、
何かアドバイスありましたらよろしくお願いいたします。</pre></pre>
引用返信 編集キー/
■14318 / inTopicNo.8)  Re[6]: ユーザコントロール内でのキーイベント無効
□投稿者/ まどか (444回)-(2008/02/15(Fri) 01:26:57)
>>(1) HogeEvents の第二引数に、KeyEventArgs を渡している。
>
> TextBox1で発生したイベント内容をそのまま引き渡したかっただけなのですが、
> 意味の無い事になっていますでしょうか。
>
> this.HogeEvents(sender, e);

HogeEventsのハンドラでFalseにしてるってことはないですよね?
eは参照型ですので変更が反映されますよ。

HogeEventsのほうは魔界の仮面弁士さんもおっしゃってますが、独自のイベントであれば独自の引数を作ったほうがいいです。
少なくとも今回の場合、Handledはイベントの祖先が結果を参照していますし、HogeEventsで関係ないのなら触れるってのは危険です。


っていうか、
Handledプロパティについては「文字は表示される」とMSDNに書いてありますね。
そしてコード例をみるとKeyPressのほうでTrueにしてる。。。
なんか、KeyPressのほうでやれと言っているように感じる今日この頃。。。
#でもKeyDownもちゃんと動くしなぁ
引用返信 編集キー/
■14319 / inTopicNo.9)  Re[7]: ユーザコントロール内でのキーイベント無効
□投稿者/ まどか (445回)-(2008/02/15(Fri) 01:29:47)
あれ?
HogeEventsの位置が↑の2件の返信で違ってますね。
やっぱりeの参照をどっかですり替えていませんか?>NewとかCloneとか
引用返信 編集キー/
■14320 / inTopicNo.10)  Re[8]: ユーザコントロール内でのキーイベント無効
□投稿者/ taguchi (19回)-(2008/02/15(Fri) 01:37:24)
2008/02/15(Fri) 11:16:16 編集(投稿者)

まどかさん
アドバイス有難うございました。

>HogeEventsのハンドラでFalseにしてるってことはないですよね?
してないつもりなのですが・・。

>HogeEventsのほうは魔界の仮面弁士さんもおっしゃってますが、独自のイベントであれば独自の引数を作ったほうがいいです。
了解しました。
意味がないのであれば、無理に引き渡す必要はありませんね。

> HogeEventsの位置が↑の2件の返信で違ってますね。
> やっぱりeの参照をどっかですり替えていませんか?>NewとかCloneとか
あ、すいません。
e.SuppressKeyPress = trueの位置を色々変えて試したりしていたので、
イベントの位置が違っていました。
上下しただけで、他は変えてないつもりです。

アドバイスありましたらよろしくお願いいたします。
引用返信 編集キー/
■14329 / inTopicNo.11)  Re[5]: ユーザコントロール内でのキーイベント無効
□投稿者/ 魔界の仮面弁士 (627回)-(2008/02/15(Fri) 11:28:13)
No14315 (taguchi さん) に返信
> MessageBox.show程度の事を行っておりますが、
> 画面遷移で何か、原因があるのでしょうか。

KeyDown/KeyPressや、MouseDown等のイベントの中では、
MessageBox の表示を行わないでください。

TextBox に渡されるはずであったキーやマウスの入力が阻害されてしまい、
以降のイベントの流れに影響を与える可能性があります。
(KeyUp が届かなかったり、DblClick が発生しなかったりなど)


たとえば下記は、「A」キーの入力を禁止するコードですが、
コメントを解除すると、禁止されずに入力できてしまう可能性があります。

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.A)
    {
        //MessageBox.Show("");
        e.SuppressKeyPress = true;
        e.Handled = true;
    }
}


メッセージ表示が必要であれば、バルーン/ラベル/ステータスバーなどを用いて
フォーカスが奪われないような方法を取ってみてください。
もしも、MessageBox への画面遷移が必要であれば、入力中ではなく、入力完了後に行ってみてください。

引用返信 編集キー/
■14331 / inTopicNo.12)  Re[6]: ユーザコントロール内でのキーイベント無効
□投稿者/ taguchi (20回)-(2008/02/15(Fri) 12:02:55)
魔界の仮面弁士さん
アドバイス有難う御座います。

> KeyDown/KeyPressや、MouseDown等のイベントの中では、
> MessageBox の表示を行わないでください。

一度、表示に関してのタイミングを変更して試してみます。
また、結果ご報告いたします。

草々
引用返信 編集キー/
■14338 / inTopicNo.13)  Re[7]: ユーザコントロール内でのキーイベント無効
□投稿者/ taguchi (21回)-(2008/02/15(Fri) 14:41:09)
2008/02/15(Fri) 14:42:57 編集(投稿者)
色々試したのですが、
ユーザコントロールを利用する側でMessageBox.Showメソッドのような、
フォーカスを移動する処理を行うと、e.SuppressKeyPress = true;は
無効になってしまうようです。

苦し紛れですが、入力させたくないキーの場合に、
SendKeys.SendWait("{BS}");を
e.SuppressKeyPress = true;の前に発生させる事で
入力されてしまった文字を消すので、
動作的には目的に適うものになりました。

#もし利用側でフォーカス移動の無いメソッドを記述しても、
#e.SuppressKeyPressプロパティー設定が機能し、
#本来の機能を果たしてくれる・・と思う。

キー押下イベント内でさらにキー押下イベントを発生させるので、
非常に危険なコーディングとなっているのは承知です。

   ユーザコントロール内コーディング
      private void textBox1_KeyDown(object sender, KeyEventArgs e)
      {
           switch (e.KeyCode)
            {
                case Keys.A:
                    if (this.HogeEvents == null)
                        break;

                    SendKeys.SendWait("{BS}");//強制的に消す
                    e.SuppressKeyPress = true;//KeyDown入力無効
                    this.HogeEvents(sender, EventArgs.Empty);
                    break;

               case Keys.Back:
                    //イベント禁止
           break;
            }
       }

    利用側コーディング
      private void userControl1_HogeEvents(object sender, EventArgs e)
       {
             MessageBox.Show("A KeyDown HogeEvents");
       }

どう影響が出るかは、やってみないとわかりませんが、
とりあえずこの方法で凌ぎたいと思います。
アドバイスいただいた皆さん有難う御座いました。
他に良い方法がありましたら、是非ご教授願います。

解決済み
引用返信 編集キー/
■14340 / inTopicNo.14)  Re[8]: ユーザコントロール内でのキーイベント無効
□投稿者/ 魔界の仮面弁士 (628回)-(2008/02/15(Fri) 16:02:47)
2008/02/15(Fri) 16:11:37 編集(投稿者)
No14338 (taguchi さん) に返信
> this.HogeEvents(sender, EventArgs.Empty);
sender を渡してしまってはマズイのでは無いでしょうか。

HogeEvents を管理しているのは、UserControl "Hoge" であって、
内包コントロール "HogeTextBox" では無いのですから。


> 他に良い方法がありましたら、是非ご教授願います。

「良い方法」と限定されてしまうと、微妙に発言しにくいですが…とりあえず
イベントを生成させるタイミングを変更してみては如何でしょうか。(未確認)

e.SuppressKeyPress = true;
e.Handled = true;
if (this.HogeEvents != null)
{
    //this.HogeEvents(this, EventArgs.Empty);
    this.BeginInvoke(this.HogeEvents, this, EventArgs.Empty);
}

引用返信 編集キー/
■14349 / inTopicNo.15)  Re[9]: ユーザコントロール内でのキーイベント無効
□投稿者/ taguchi (22回)-(2008/02/15(Fri) 18:09:37)
魔界の仮面弁士さん
アドバイス有難う御座います。

> HogeEvents を管理しているのは、UserControl "Hoge" であって、
> 内包コントロール "HogeTextBox" では無いのですから。

その点を曖昧に理解していました。
やはり、管理基点が存在するのですね。

> イベントを生成させるタイミングを変更してみては如何でしょうか。(未確認)
> 
> e.SuppressKeyPress = true;
> e.Handled = true;
> if (this.HogeEvents != null)
> {
>     //this.HogeEvents(this, EventArgs.Empty);
>     this.BeginInvoke(this.HogeEvents, this, EventArgs.Empty);
> }

この非同期と言うやり方で上手く動きました。
なるほど、非同期ならコントロールが独自のイベントを処理してくれるんですね。
有難う御座いました。

#魔界の仮面弁士さん。流石です。毎回感服しきりです。
#有難う御座いました。
#超初心者の私ですが、これからもC#勉強、精進いたします。
#今後とも宜しくお願い致します。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -