2017-03-17 6 views
0

私は、公開されたプロパティに基づいて、実行時に読み込むときにいくつかのことを行う必要があるカスタムコントロールを持っています。しかし、私は発行されたプロパティをチェックするたびにまだ設定されておらず、常にデフォルト値になっている問題に遭遇しています。実行時にパブリッシュプロパティが割り当てられるのはいつですか?

まずコンストラクタのコントロールのプロパティをチェックしようとしましたが、まだロードされていないことがすぐに判明しました。コントロールが画面に表示されているときにプロパティが正しく設定されているため、プロパティがまったく読み込まれていないという問題はありません。

私は次にLoaded Methodをオーバーライドしようとしましたが、同じ問題がまだ残っていますので、これは私が探しているものとは限りません。

void __fastcall TFmSearchBar::Loaded() 
{ 
    TEdit::Loaded(); //call base class loaded 

    if(MyProperty) 
    { 
     //do stuff 
    } 
} 

これらの公開プロパティは実際にどの時点で設定されていますか?

プロパティが正しく設定されるとすぐに、これらのプロパティに基づいて自分のコントロールでいくつかのロジックを実行するにはどのような方法が必要ですか?

+0

"*同じ問題がまだ残っています*" - これは正確に何ですか?あなたは実際の問題が何であるか説明しませんでした。 –

答えて

1

コントロールのコンストラクタでプロパティをチェックすると、デザイナで別途指定した場合でもプロパティは常にデフォルト値になります。

設計時の値がまだ割り当てられていないため、修正します。

これらの公開プロパティは実際にどの時点で設定されていますか?

所有者(フォーム、フレーム、またはデータモジュール)が構築されているとき。独自のDFMリソースを読み込んで解析し、格納されている子コンポーネントを構築し、そのプロパティ値を読み込みます。例えば

、あなたは以下のDFMを持っていると言う:

object Form1: TForm1 
    Left = 0 
    Top = 0 
    Caption = 'Form1' 
    ... 
    object Edit1: TEdit 
    Left = 136 
    Top = 64 
    Width = 121 
    Height = 21 
    TabOrder = 0 
    end 
    object Button1: TButton 
    Left = 263 
    Top = 62 
    Width = 75 
    Height = 25 
    Caption = 'Button1' 
    TabOrder = 1 
    end 
end 

DFMストリーミングプロセスは大体(私は簡単にするために外に内部の詳細の多くを残している)は、次の同等のコードに変換します。

__fastcall TCustomForm::TCustomForm(TComponent *Owner) 
    : TScrollingWinControl(Owner) 
{ 
    this->FFormState << fsCreating; 
    try 
    { 
     // locate, load, and parse the "Form1" DFM resource ... 

     this->FComponentState << csLoading; 
     this->Parent = ...; 
     this->Name = L"Form1": 
     this->FComponentState << csReading; 
     this->Left = 0; 
     this->Top = 0; 
     this->Caption = L"Form1"; 
     ... 

     TEdit *e = new TEdit(this); 
     try 
     { 
      e->FComponentState << csLoading; 
      e->Parent = this; 
      e->Name = L"Edit1"; // <-- sets the derived Form's 'Edit1' member to this object 
      e->FComponentState << csReading; 
      e->Left = 136; 
      e->Top = 64; 
      e->Width = 121; 
      e->Height = 21; 
      e->TabOrder = 0; 
      e->FComponentState >> csReading; 
     } 
     catch (...) 
     { 
      delete e; 
      throw; 
     } 

     TButton *b = new TButton(this); 
     try 
     { 
      b->FComponentState << csLoading; 
      b->Parent = this; 
      b->Name = L"Button1"; // <-- sets the derived Form's 'Button1' member to this object 
      b->FComponentState << csReading; 
      b->Left = 263; 
      b->Top = 62; 
      b->Width = 75; 
      b->Height = 25; 
      b->Caption = L"Button1"; 
      b->TabOrder = 1; 
      b->FComponentState >> csReading; 
     } 
     catch (...) 
     { 
      delete b; 
      throw; 
     } 

     this->FComponentState >> csReading; 

     ... 

     e->Loaded(); 
     b->Loaded(); 
     this->Loaded(); 
    } 
    __finally 
    { 
     this->FFormState >> fsCreating; 
    } 
} 

このように、コンポーネントのプロパティ値は、コンストラクタが呼び出されたときにはまだ使用できません。

/私は、すぐにプロパティが正しく設定されているとして、これらの特性に基づいて、私のコントロールでいくつかのロジックを実行するためににどのような方法をフックする必要がありますすることができますか?

これは、プロパティの処理内容によって異なります。すぐに操作を実行する必要がある場合は、プロパティーセッターで直接操作できます。しかし、他のプロパティが最初に読み込まれるまで待つ必要がある場合(一方のプロパティが別のプロパティの値に依存する場合)、代わりに仮想Loaded()メソッドをオーバーライドします。これはDFMストリーミングが終了した後に自動的に呼び出されます。プロパティ設定者は、プロパティのフラグをチェックして、設計時にDFMが現在ストリーミングされているかどうかなど、コンポーネントが現在フォームデザイナで実行されているかどうかを確認し、必要に応じて動作させることができます。

私がロードされたメソッドをオーバーライドすることが、まだ正確に何である同じ問題

を持っていますしようとしましたか?あなたは実際の問題が何であるか説明しませんでした。これらの詳細を提供するにはedit your questionを入力してください。

だから、私はこれがまさに私が探しているものだとは思わない。

おそらく、正しく使用していない可能性があります。

+0

ご連絡ありがとうございます。私は問題をよりよく述べるために質問を編集しました。 settersを使用することは理にかなっていて、後で見ると非常に明白です:) Loadedメソッドまでは、プロパティ値をチェックするためにブレークポイントを設定しましたが、その時点ではデフォルト値に設定されていました。 –

+0

@JamesHogle: 'Loaded()'は、オーバーライドする正しい方法です。これはストリーミングシステムの信号で、すべてのDFMプロパティがストリーミングされ、使用できる状態になっています。それがあなたのために働いていないなら、何か他のことが起こっています。実際に動作していないコードを表示する必要があります。 –

関連する問題