none
Property Set が親コンテナのInitializeComponent から呼び出されたかどうかを判断 RRS feed

  • 質問

  •  #VB2005

    ユーザーコントロールを作成しています。
    たとえば、ラベルの右横にテキストボックスがあるユーザーコントロールとします。
    ここで、UserControl1.LabelText = "ABC" とした場合、テキストボックスが左右にずれるのではなくて、
    テキストボックスの位置は変わらずラベルの左端が変化するという挙動をさせています。
    つまり、ラベルの幅の差分を x とした場合、
    UserControl1.Left = UserControl1.Left - x, UserControl1.Width = UserControl1.Width + x
    となる動きです。

    上記のプロパティはプロパティウィンドウでも操作でき、次の場合は正しく動作します。

    ・新規にユーザーコントロールを貼り付けたとき。
    ・貼り付けてからデザイナ上でのプロパティ変更

    正しくとは、貼り付けたときはまだユーザーコントロールに対する自動生成コードが無いため
    デザイナ上での位置(UserControl1.Location)が期待する位置と一致するということです。

    ここで、貼り付けた状態で次の場合、
    つまり貼り付けた親コンテナのInitializeComponentが実行されるときに位置がずれてしまいます。
    #上記の挙動の処理が実行されるため当然ですが

    ・ユーザーコントロールをビルドしたあとのデザイナ
    ・実行時の親コンテナのコンストラクタからの流れ

    回避策として、

    ・親コンテナのInitializeComponentからProperty Setが呼び出されたかを判断する
     #またはそういうタイミング(状況)である
    ・今回の挙動をする関連プロパティをデザイナ上すべてDefaultValue値としておき、親コンテナのユーザーコードで設定する。

    がありますが、
    前者のInitializeComponentから呼び出されたかを判断する方法について情報をお待ちしております。
    #最悪トレースを見てとかであればあきらめます。

    2009年2月2日 12:09

回答

  • まどか の発言: 今回のはリサイズの問題ではなく移動ですし、Anchorは外に依存する動作なので
    残念ながら使えません。。。

    ラベルテキストが変化するとラベル幅も変化します。
    このときにラベルの右端の位置を固定でLeft座標をずらそうとしています。

    質問を読み違えたかな…。
    質問に対する答えとして、ISupportInitializeインターフェースを実装すると解決できるのではと思います。
    このインターフェースを実装するとInitializeComponent()はBeginInit()とEndInit()を呼んでくれますので、

    bool initializing;  
    void BeginInit(){  
      initializing = true;  
    }  
    void EndInit(){  
      initializing = false;  

    (あ、VBじゃなくてすみません)
    としておけば、initializingフラグで識別できるようになります。

    • 回答としてマーク まどか 2009年2月3日 1:08
    2009年2月2日 13:59

すべての返信

  • 全然、別のアプローチでControl.Anchorプロパティは使えませんか?
    デフォルトではTop, Leftとなっていますが「ラベル」およびUserControl1のAnchorをTop, Rightにしてみてください。
    右上を起点にリサイズが行われるようになります。

    2009年2月2日 12:51
  • 佐祐理さん の発言:

    全然、別のアプローチでControl.Anchorプロパティは使えませんか?
    デフォルトではTop, Leftとなっていますが「ラベル」およびUserControl1のAnchorをTop, Rightにしてみてください。
    右上を起点にリサイズが行われるようになります。



    今回のはリサイズの問題ではなく移動ですし、Anchorは外に依存する動作なので
    残念ながら使えません。。。

    ラベルテキストが変化するとラベル幅も変化します。
    このときにラベルの右端の位置を固定でLeft座標をずらそうとしています。
    2009年2月2日 13:31
  • まどか の発言: 今回のはリサイズの問題ではなく移動ですし、Anchorは外に依存する動作なので
    残念ながら使えません。。。

    ラベルテキストが変化するとラベル幅も変化します。
    このときにラベルの右端の位置を固定でLeft座標をずらそうとしています。

    質問を読み違えたかな…。
    質問に対する答えとして、ISupportInitializeインターフェースを実装すると解決できるのではと思います。
    このインターフェースを実装するとInitializeComponent()はBeginInit()とEndInit()を呼んでくれますので、

    bool initializing;  
    void BeginInit(){  
      initializing = true;  
    }  
    void EndInit(){  
      initializing = false;  

    (あ、VBじゃなくてすみません)
    としておけば、initializingフラグで識別できるようになります。

    • 回答としてマーク まどか 2009年2月3日 1:08
    2009年2月2日 13:59
  • 佐祐理さん の発言:

    ISupportInitializeインターフェースを実装すると解決できるのではと思います。
    このインターフェースを実装するとInitializeComponent()はBeginInit()とEndInit()を呼んでくれますので、

    まさに目的そのものでした。
    ありがとうございます。

    2009年2月3日 1:08