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

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

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

Re[5]: ユーザーコントロールのロストフォーカス


(過去ログ 107 を表示中)

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

■63673 / inTopicNo.1)  ユーザーコントロールのロストフォーカス
  
□投稿者/ 来年こそは! (1回)-(2012/09/25(Tue) 09:20:21)

分類:[VB.NET/VB2005 以降] 

ユーザーコントロールを始めて作ろうと思っているど素人です。
現在、作ろうと思ったのは
テキストボックスにフォーカスが移った時にバックカラーを変えて、常に全選択状態にしてフォーカスが抜けた時にバックカラーを変える
テキストボックスに何か入力されていたらバクカラーを変える。
この一連の動作をユーザーコントロールで作成しました。
テスト用にプロジェクトを作り、そこにユーザーコントロールを貼り付けて動作確認をしました。
ユーザーコントロールで自作した部分はきちんと動くのですが、テスト用に作ったプロジェクトに貼り付けたユーザーコントロールのテキストボックスに
ロストフォーカスが動かないのです。
リーブは動きます。
やはりユーザーコントロールのイベントの方が先に動くので無理なのでしょうか?
素人なので説明も下手ですし、理解して頂けたでしょうか?
ユーザーコントロールでもロストフォーカスしてるし貼り付けた新たに作るプロジェクトでもロストフォーカスしているから
なんか動作がおかしいのでしょうか?
読みにくくて本当にすみません。
どうか宜しくお願致します。

言語はVB.net2010
OSはWin7


引用返信 編集キー/
■63674 / inTopicNo.2)  Re[1]: ユーザーコントロールのロストフォーカス
□投稿者/ じゃんぬねっと (5回)-(2012/09/25(Tue) 09:48:55)
じゃんぬねっと さんの Web サイト
No63673 (来年こそは! さん) に返信
> ユーザーコントロールを始めて作ろうと思っているど素人です。
> 現在、作ろうと思ったのは
> テキストボックスにフォーカスが移った時にバックカラーを変えて、常に全選択状態にしてフォーカスが抜けた時にバックカラーを変える
> テキストボックスに何か入力されていたらバクカラーを変える。
> この一連の動作をユーザーコントロールで作成しました。
> テスト用にプロジェクトを作り、そこにユーザーコントロールを貼り付けて動作確認をしました。
> ユーザーコントロールで自作した部分はきちんと動くのですが、テスト用に作ったプロジェクトに貼り付けたユーザーコントロールのテキストボックスに
> ロストフォーカスが動かないのです。
> リーブは動きます。
> やはりユーザーコントロールのイベントの方が先に動くので無理なのでしょうか?
> 素人なので説明も下手ですし、理解して頂けたでしょうか?
> ユーザーコントロールでもロストフォーカスしてるし貼り付けた新たに作るプロジェクトでもロストフォーカスしているから
> なんか動作がおかしいのでしょうか?
> 読みにくくて本当にすみません。
> どうか宜しくお願致します。
>
> 言語はVB.net2010
> OSはWin7

"ユーザーコントロール" とありますが、複合コントロールのコンテナですか?
拡張コントロール (標準 Control から継承されたカスタム コントロール) ではなくて?
でも現象からするとコンテナがあるような動作ですので、複合コントロールっぽいですね。

拡張コントロールであれば、Leave イベントで特に何も困ることなく仕様を全うできると思います。
逆の言い方をすると、上記仕様で複合コントロールにする必要はありません。

> ロストフォーカスが動かないのです。
> リーブは動きます。

そもそも LostFocus イベントは .NET 1.x 時代からすでに非推奨のイベントです。
Leave イベントで行うのが正しいです。
LostFocus イベントは当該コントロールがフォーカスを失った時だけではなく、コンテナまたはウィンドウが Deactivate の時にもイベントが発生することがあります。
コンテナはともかくとして、ウィンドウの Deactivate のタイミングでイベントが発生するのはまずいでしょう。
引用返信 編集キー/
■63675 / inTopicNo.3)  Re[2]: ユーザーコントロールのロストフォーカス
□投稿者/ 来年こそは! (3回)-(2012/09/25(Tue) 10:02:53)
No63674 (じゃんぬねっと さん) に返信
> ■No63673 (来年こそは! さん) に返信
>>ユーザーコントロールを始めて作ろうと思っているど素人です。
>>現在、作ろうと思ったのは
>>テキストボックスにフォーカスが移った時にバックカラーを変えて、常に全選択状態にしてフォーカスが抜けた時にバックカラーを変える
>>テキストボックスに何か入力されていたらバクカラーを変える。
>>この一連の動作をユーザーコントロールで作成しました。
>>テスト用にプロジェクトを作り、そこにユーザーコントロールを貼り付けて動作確認をしました。
>>ユーザーコントロールで自作した部分はきちんと動くのですが、テスト用に作ったプロジェクトに貼り付けたユーザーコントロールのテキストボックスに
>>ロストフォーカスが動かないのです。
>>リーブは動きます。
>>やはりユーザーコントロールのイベントの方が先に動くので無理なのでしょうか?
>>素人なので説明も下手ですし、理解して頂けたでしょうか?
>>ユーザーコントロールでもロストフォーカスしてるし貼り付けた新たに作るプロジェクトでもロストフォーカスしているから
>>なんか動作がおかしいのでしょうか?
>>読みにくくて本当にすみません。
>>どうか宜しくお願致します。
>>
>>言語はVB.net2010
>>OSはWin7
>
> "ユーザーコントロール" とありますが、複合コントロールのコンテナですか?
> 拡張コントロール (標準 Control から継承されたカスタム コントロール) ではなくて?
> でも現象からするとコンテナがあるような動作ですので、複合コントロールっぽいですね。
>
> 拡張コントロールであれば、Leave イベントで特に何も困ることなく仕様を全うできると思います。
> 逆の言い方をすると、上記仕様で複合コントロールにする必要はありません。
>
>>ロストフォーカスが動かないのです。
>>リーブは動きます。
>
> そもそも LostFocus イベントは .NET 1.x 時代からすでに非推奨のイベントです。
> Leave イベントで行うのが正しいです。
> LostFocus イベントは当該コントロールがフォーカスを失った時だけではなく、コンテナまたはウィンドウが Deactivate の時にもイベントが発生することがあります。
> コンテナはともかくとして、ウィンドウの Deactivate のタイミングでイベントが発生するのはまずいでしょう。

じゅんぬねっと様
ご返信有難う御座います。
いつもじゃんぬねっと様のサイトやあちこちの書き込みに助けられています。
この場を借りて、あらためてお礼をさせて頂きます。

さて、本題ですが、、、
複合コントロールやカスタム コントロールの言葉の意味がわかりませんが
プロジェクトからユーザーコントロールの追加で作成した物になります。


LostFocus では無くLeave にしてやってみます。

とりあえず検証前ですがお礼を記載させて頂きました。
検証が済みましたらもう一度結果報告させて頂きます。

PS

> 拡張コントロール (標準 Control から継承されたカスタム コントロール) ではなくて?

う〜ん奥が深い。。こんな事も出来るんですね。勉強になりました。

引用返信 編集キー/
■63676 / inTopicNo.4)  Re[3]: ユーザーコントロールのロストフォーカス
□投稿者/ shu (78回)-(2012/09/25(Tue) 10:21:37)
2012/09/25(Tue) 10:21:58 編集(投稿者)

No63675 (来年こそは! さん) に返信

> 複合コントロールやカスタム コントロールの言葉の意味がわかりませんが
複合コントロール => ユーザーコントロールの追加とすると複数のコントロールを配置出来る
    コントロールを作ることが出来ます。複数が合わさっているので複合

カスタムコントロール
=>
>>拡張コントロール (標準 Control から継承されたカスタム コントロール) ではなくて?
>
> う〜ん奥が深い。。こんな事も出来るんですね。勉強になりました。
わかってますね。
引用返信 編集キー/
■63677 / inTopicNo.5)  Re[4]: ユーザーコントロールのロストフォーカス
□投稿者/ 来年こそは! (4回)-(2012/09/25(Tue) 11:48:28)
でけた〜

長文になりますが、ご興味が有る方だけお読み下さい。
今後の為に、参考にする方、自分へのメモの為に対処した全てを記載致します。

★最初に余談★
自分は高校を卒業してガソリンスタンドで働いていました。PGになる事を夢見てこの世界に入り、今日が丁度1年目です。
何故?夢を見たかと言うと『じゃんぬねっと様』のサイトを見ながら日曜プログラムを作っていて
「あ〜じゃんぬさんみたいになんでも出来る人になりたいな〜」と思ったのがきっかけでした。
そんなあこがれの人に返信貰ったのでちょっと余談を記載しました。

ここから本題

最初に拡張コントロールでググりました。
下記サイトにたどり着きました。
http://shinshu.fm/MHz/88.44/archives/0000023336.html

ふむふむ、そして下記も参考にしました。
http://msdn.microsoft.com/ja-jp/library/w2a8y03d(v=vs.100).aspx

最初にWindows フォーム コントロール ライブラリを作成します。
2番目のサイトを見て作成しました。

そして、1番目のサイトをヒントに
下記コードを書きました。

#Region "【Leav】"
'--LostFocus
Protected Overrides Sub OnLeave(e As System.EventArgs)
'--LostFocus時の背景色を設定
Me.BackColor = Color.White
MyBase.OnLeave(e)
End Sub
#End Region
#Region "【GotFocus】"
'--GotFocus
Protected Overrides Sub OnGotFocus(ByVal e As EventArgs)

'--GotFocus時の背景色を設定
Me.BackColor = Color.Cyan
MyBase.OnGotFocus(e)

End Sub
#End Region
#Region "【KeyDown】"
'--KeyDown
Protected Overrides Sub OnKeyDown(ByVal e As KeyEventArgs)

'--エンターキー押下時(Shiftは押されていない)時、次のコントロールへ移動する。
If e.KeyCode = Keys.Return And e.Shift = False Then
SendKeys.Send("{Tab}")
End If

'--エンターキー押下時(Shiftは押されている)時、前のコントロールへ移動する。
If e.KeyCode = Keys.Return And e.Shift = True And e.Control = False Then
SendKeys.Send("+{Tab}")
End If

MyBase.OnKeyDown(e)
End Sub
#End Region

リビルドして、新規プロジェクトに作ったものを貼り付けたら
見事に動きました。

いや〜奥が深いけど出来たら感動ですね〜
「Windows フォーム コントロール ライブラリを作成すればいいんだ!」とたどり着くのに
1時間悩みました。

コードがおかしかったら指摘して貰えると助かります。

本当に本当に本当に本当に本当に本当に
じゃんぬねっと様、shu様
ご返信頂きまして、有難う御座います。

しばらくはこの業界にしがみついていけそうです。

解決済み
引用返信 編集キー/
■63678 / inTopicNo.6)  Re[5]: ユーザーコントロールのロストフォーカス
□投稿者/ じゃんぬねっと (6回)-(2012/09/25(Tue) 15:26:05)
じゃんぬねっと さんの Web サイト
No63677 (来年こそは! さん) に返信
> いや〜奥が深いけど出来たら感動ですね〜
> 「Windows フォーム コントロール ライブラリを作成すればいいんだ!」とたどり着くのに
> 1時間悩みました。

細かいところかもしれませんが、少し誤解があるかもしれませんので...

作成したコントロールを他で使用するとなると DLL にしておきたいので、そういう意味では正解です。
ただ、自作のコントロールはライブラリ プロジェクトでなくても作成できます。
プロジェクトのタイプは、そのプロジェクトがビルドされた結果生成されるアセンブリの種類であったりひな型であったり、実行される時のタイプであったりして少しややこしいですね。

> コードがおかしかったら指摘して貰えると助かります。

では少しだけ書いてしまいます。

> Protected Overrides Sub OnGotFocus(ByVal e As EventArgs)

GotFocus イベントも先のポストで説明した LostFocus イベントと同様の理由で非推奨のイベントです (GotFocus イベントはウィンドウが Activate になったタイミングでも発生してしまうことがあります)。
こちらは Enter イベントが正しいですので、オーバーライドすべきは OnEnter メソッドになります。

> Protected Overrides Sub OnKeyDown(ByVal e As KeyEventArgs)

これが仕様ということであれば 「間違い」 というわけではないですが...

このコントロールを利用する側で KeyDown イベントの挙動が変わる可能性を考慮しなくてはなりません。
今の実装ですと、キーをインターセプトしているので利用する側のプロジェクトは、フォーカスが遷移した後となり厳密ではありません。
利用する側でコントロールの内部実装 (処理順序や行われていること) を意識しなくてはならないのは、コンポーネントとしてはあまり良い状態ではありません。

行儀よくやるならば、先に基底クラス側のメソッドを呼び出し、イベント引数 Handled を確認した後にフォーカス遷移の処理を実装すべきです。
こうしておかないと、利用する側で 「このキーのイベントはすでに処理されたので、フォーカス遷移したくない」 という実装ができにくくなります。

それと OnKeyDown メソッドではなく、OnPreviewKeyDown メソッドの使用を検討してください。
今回は違うので蛇足ですが、特殊キーやプロセス キーだった場合は、また別のメソッドのオーバーライドしなければなりませんので、常にこのメソッドで良いというわけではありません。

> If e.KeyCode = Keys.Return And e.Shift = False Then
> If e.KeyCode = Keys.Return And e.Shift = True And e.Control = False Then

細かいところですが、ショートサーキット評価の AndAlso 演算子を使った方が良いです。
それと e.Control の判定は上の場合でも入れておいた方が良いです。
MultiLine な TextBox に改行コードを入力したい場合に、Control キーを押下しながら入力することでエスケープできるからです。
今の状態だと、Shift + Control + Enter でないと改行コードが入力できないです。

> SendKeys.Send("{Tab}")
> SendKeys.Send("+{Tab}")

SendKeys クラスは使用しない方が良いです。
SelectNextControl メソッドなどを利用するようにしましょう。
挙動が気に入らない場合は、GetNextControl メソッドと組み合わせて自作しましょう。

> Me.BackColor = Color.White

コントロール背景色は白 (#FFFFFF) とは限りません。
環境設定で白以外に設定できるからです。
ここは SystemColors.Window を使いましょう。

> Me.BackColor = Color.Cyan

(これは間違いの指摘ではありません)
せっかくカスタム コントロールを作るわけですから、BackColor の色がプロパティで設定できたりするとうれしいですよね。

--

もっと言えば、今回のような 「振る舞い」 的な機能は拡張コントロールで実装するのではなく、拡張プロバイダやコンポーネントで実装した方が良いです。
私も 2005 時代までは、いろんな掲示板で拡張コントロールを奨めてしまっていました (今は猛省しています)。
最近になって、これは間違いではないが多分に最適解ではないと思うようになりました。

たとえば、TextBox 以外のコントロールでも似たような装飾する機能が欲しくなった場合を考えます。
そのコントロールごとにわざわざ拡張コントロールを作成するのか? という話になりますよね。
拡張プロバイダにすれば、こういった振る舞いは一元化でき、他のコントロールでも流用が可能です。
(拡張プロバイダの最もわかりやすい例は ToolTip あたりでしょうか)

また拡張コントロールは通常たくさんの機能を詰め込みすぎて、作成者以外仕様がわかりにくくなることがあります。
拡張プロバイダにすれば 「Active なコントロールの背景色が変わる」 という機能でひとつの拡張プロバイダにすることができます。
つまり、時と場合に合わせて、欲しい機能の組み合わせができるということですね。
拡張コントロールで機能を一部だけ無効にしたい場合は、わざわざプロパティで機能ごとの 「有効/無効」 を用意しなければなりません。

ちなみに私は、
 ・任意のキーでフォーカスを遷移できるものはコンポーネント
 ・背景色の変更や、エラーチェック、ShortcutKey などは拡張プロバイダ
 ・仮想ファンクションなど UI が固有で必要なものはカスタム コントロール
と使い分けをして仕事でもバリバリ使っています。

> じゅんぬねっと

(^-^;)
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -