InitLayoutよりも後に実行されるイベントは?

解決


唯香  2010-04-08 18:36:59  No: 146803  IP: [192.*.*.*]

いつも参考にさせていただいております。

初めてカスタムコントロールを作成しているのですが
イベントの発生順序がわからず投稿させていただきました。

今DateTimePickerを継承したコントロール(カスタムコントロール?)を作成しています。

アプリケーションの種類はDLLを作ろうと思っていないので
Windows フォーム アプリケーションです。
(既にいくつかフォームが存在しています)

[追加]-[カスタムコントロール]でプロジェクトに追加し
デザインを開いてInheritsをSystem.Windows.Forms.DateTimePickerに変更しました。

自動的にできるOnPaintの記述は使わないので削除しました。

このファイルはカスタムコントロールって呼ぶので合っていますか?
デザインファイルを修正したので違うものになっているのでしょうか?


すいません。本当に知りたいのはココからなのですが
Private FormatString As Stringというのを定義してあるので
デザイン時に設定されたCustomFormatを保存しておきたいのですが
どこに書けばいいのかがわかりません。

初めは単純に「Public Sub New()」の一番最後の行に書いていたのですが
NewコンストラクタではCustomFormatはいつもNothingです。

調べてみると「Protected Overrides Sub InitLayout()」の方が
Newよりも後で実行されるようなので変更してみたのですが
InitLayoutでもCustomFormatがNothingです。


今はFormatChangedでFormatStringがNothingかどうかを判断して
保存するような仕組みにしているのですが
FormatStringが何度もに変更になるような仕様なので
できればInitLayoutより後に1回だけ起こるイベントをご存知でしたら
ご教授よろしくお願いします。


VB2008/XPPro

編集 削除
特攻隊長まるるう  2010-04-09 10:10:21  No: 146804  IP: [192.*.*.*]

端的に表現したいなら「DateTimePicker継承コントロール」でしょう。
ユーザーがカスタマイズした独自のコントロールという意味で、
カスタムコントロールやユーザーコントロールでも間違いでは無い
ですが、継承してないものも含まれてしまいます。そして、継承して
いる事が重要な情報となります。

ただし、質問者が継承を理解しているのかどうか分かりませんし、
再現手順として実際にやった事を書いているのが非常に分かり易い
です(余計な確認をしなくて済みます)。

まず、デザイン時に設定されたプロパティ値を誰がいつ設定している
かご存知でしょうか?デザイン画面での変更がコードとして保存されて
います。

[ソリューションエクスプローラ]上部のアイコンで[すべてのファイル
を表示]にしてください。Form1.vb ファイルの下に Form1.Designer.vb
というファイルが確認できるでしょうか?ここにフォームの New から
実行されるコントロールの初期化処理(InitializeComponent)が書かれ
ます。

つまり、コントロールのレベルでは、どこまでいってもデザイン画面
の設定は反映されません。フォームの上に配置した時に、フォームが
設定しているのです。
従って、フォームの New 内で InitializeComponent の後に書くのが
一般的です。フォームの New は VB に自動で書いてもらって下さい。
自動で書かれるコードを省略してますが、概要は以下のような感じに
なります。
[VB2008]
Partial Class Form1
    Inherits System.Windows.Forms.Form

    Public Sub New()

        ' この呼び出しは、Windows フォーム デザイナで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        Call MyInitialize()

    End Sub

    Private Sub MyInitialize()
        Me.MyDateTimePicker1.FormatString = Me.MyDateTimePicker1.CustomFormat
    End Sub

End Class

編集 削除
唯香  2010-04-09 14:17:23  No: 146805  IP: [192.*.*.*]

特攻隊長まるるう様いつも目をかけてくださりありがとうございます。

>端的に表現したいなら「DateTimePicker継承コントロール」でしょう。

「DateTimePicker継承コントロール」ですね。覚えておきます。


>ただし、質問者が継承を理解しているのかどうか分かりませんし、
>再現手順として実際にやった事を書いているのが非常に分かり易い
>です(余計な確認をしなくて済みます)。

すいません。よく分かってないです。。
苺のケーキを作るのにスポンジオブジェクトをInheritsすれば
あとは生クリームと苺を乗せるだけみたいな物と思っています。


>つまり、コントロールのレベルでは、どこまでいってもデザイン画面
>の設定は反映されません。フォームの上に配置した時に、フォームが
>設定しているのです。

なるほど!!すごく納得できました!
DateTimePicker継承コントロール側は
使われた後のことは分からないんですね。


>従って、フォームの New 内で InitializeComponent の後に書くのが
>一般的です。フォームの New は VB に自動で書いてもらって下さい。
>自動で書かれるコードを省略してますが、概要は以下のような感じに
>なります。

コードの提示ありがとうございます。
FormatStringをPublicにしてMyInitializeをコピペしたところうまくいきました。


ちなみにまた違う質問で申し訳ないのですが
NewコンストラクタはいつもPartial Class(Designer.vb)ではなく
いつもPublic Class Form1(vb)の方で書いちゃってたのですが問題でしょうか?

編集 削除
魔界の仮面弁士  2010-04-09 19:36:04  No: 146806  IP: [192.*.*.*]

>>> このファイルはカスタムコントロールって呼ぶので合っていますか?
間違いだとは言い切れませんが、狭義の『カスタムコントロール』とは、
公式には「素の Control クラス」を直接継承したコントロールを指します。

今回のような物は、『拡張コントロール』と呼ばれています。
http://msdn.microsoft.com/ja-jp/library/w29y3h59.aspx
http://msdn.microsoft.com/ja-jp/library/ms171725.aspx


≪拡張コントロール (Extended Controls)≫
既存のコントロールを継承して作られたコントロールです。今回のように、
継承元のクラスを明示して「DateTimePicker継承コントロール」などと
表記されることもあります。

≪カスタム コントロール (Custom Controls)≫
素の Control クラスから継承させて作ったコントロールを指します。
多くの場合、OnPaint や WndProc も実装することになるため、.NET 自体の
開発知識だけではなく、Windows API に関する開発知識も要求されます。

≪複合コントロール (Composite Controls)≫
既存のコントロールを複数内在させて作られたコントロールを指します。
一般的には、UserControl クラス上に複数のコントロールを載せて
作成されるため、ユーザーコントロールと呼ばれることもあります。

≪ActiveX コントロール (ActiveX Controls)≫
.NET ではなく、COM のテクノロジーを用いて作成されたコントロールです。
VB5, VB6 で作成できますが、VB.NET での作成は困難です(VB.NET での利用は可能)。
OLE カスタムコントロールや OCX などと呼ばれることもあります。

≪ウィンドウレス コントロール (Windowless Controls)≫
軽量コントロール (Lightweight Controls)とも呼ばれるコントロールです。
VB.NET からは、通常の ActiveX コントロールとして利用できますが(多少の制限あり)、
VB.NET および VB5 以下で作成することはできません(VB6 で作成することは可能)。


> NewコンストラクタはいつもPartial Class(Designer.vb)ではなく
> いつもPublic Class Form1(vb)の方で書いちゃってたのですが問題でしょうか?
それで良いと思いますよ。
極力、.Designer.vb は自動生成されたままにしておいた方が無難かと。

編集 削除
特攻隊長まるるう  2010-04-13 15:28:46  No: 146807  IP: [192.*.*.*]

> 極力、.Designer.vb は自動生成されたままにしておいた方が無難かと。
賛成です。Partial はヘルプに書いてある通り、クラスの一部分を取り出したように
扱われるので、VBの仕様的にはどちらでも良いのですが、自動で書かれるコードは今後も
自動で編集されます。ただでさえ平気で壊れちゃうのに、自前のコードを含ませると、
壊れる確率が多少なりとも上がります。自前のコードとは別管理が良いです。
# とはいえ、中級者以上は必要になったらバックアップを保存しておいて迷わず編集するでしょうがw

今回は InitializeComponent を意識してもらう為に .Designer.vb に書きましたが、
Public Class Form1(vb)の方に書くべきです。MyInitialize 関数も同様です。

編集 削除
唯香  2010-04-13 15:29:41  No: 146808  IP: [192.*.*.*]

魔界の仮面弁士様いつもお返事頂きありがとうございます。
せっかくお返事いただいていたのに返信が遅くなりすいません。

コントロールの違いというのがいまいちよく分からなかったので
ご説明いただきとても参考になりました。

教えていただいたリンク先は今後の開発の参考になるような
チュートリアルがたくさん掲載されていてとてもよかったです。


> > NewコンストラクタはいつもPartial Class(Designer.vb)ではなく
> > いつもPublic Class Form1(vb)の方で書いちゃってたのですが問題でしょうか?
> それで良いと思いますよ。
> 極力、.Designer.vb は自動生成されたままにしておいた方が無難かと。

Designer.vbをいじってダメにした経験がありトラウマだったのでよかったです。


特攻隊長まるるう様と魔界の仮面弁士様のおかげで問題が解決しました。
文字でしか感謝の気持ちを伝えられないことをもどかしく思いますが
本当にいつも感謝しております。
ありがとうございました。

編集 削除