2009-09-01 9 views
1

アソシエートがTEditサブクラスのインスタンスに設定されているTUpDownコントロールがあります。編集クラスは、オーバーライドされたDoEnterメソッドでRecreateWndを呼び出します。残念ながら、これはAPIレベルでのバディ接続を強制終了し、これは奇妙な動作につながります。アップダウン矢印をクリックすると表示されます。アソシエートを再作成中にアップダウン - アソシエート接続を維持する

私の問題は、編集インスタンスが再接続しなければならないいくつかのアップダウンのバディであり、アップダウンにそのバディの喪失が通知されていないということです。どのように私は2つを再接続することができる任意のアイデア?

答えて

1

あなたは何か不幸なことを発見しました。アプリケーションレベルで2つのコントロール間の関連付けを設定すると、はアプリケーションレベルのコードでその関連付けを引き続き管理できますが、VCLはそれを維持するために必要なフレームワークを提供しません。理想的には、一般的な関連付けフレームワークが存在するため、関連付けられたコントロールは、自分自身で更新する必要があることを互いに通知することができます。

VCLの最初の部分は、Notificationメソッドですが、破棄されるコンポーネントのみに通知されます。

あなたの提案する解決策は、タスクにはあまりにも具体的だと思います。エディットコントロールは、アップダウンコントロールにアタッチされていることを必ずしも知らなくてはならず、そうであっても、親を共有する必要はありません。一方、この問題のための全体的なオブザーバーフレームワーク全体を書くことは、過度のことです。私は妥協を提案する。エディットコントロールに新しいイベントプロパティと

スタート:

property OnRecreateWnd: TNotifyEvent read FOnRecreateWnd write FOnRecreateWnd; 

あなたは上記したよう次にRecreateWndをオーバーライドし、代わりにすべてのアップダウンコントロール固有のコードの、単にイベントをトリガ:

procedure TAlignedEdit.RecreateWnd; 
begin 
    inherited; 
    if Assigned(OnRecreateWnd) then 
    OnRecreateWnd(Self); 
end; 

ここで、アプリケーションコード内で、どのコントロールが関連付けられているかを正確に知っているイベントを処理して、何も検索する必要がなく、子供関係:

procedure TUlrichForm.AlignedEdit1RecreateWnd(Sender: TObject); 
begin 
    Assert(Sender = AlignedEdit1); 
    UpDown1.Associate := nil; 
    UpDown1.Associate := AlignedEdit1; 
end; 
+0

親を共有する必要があるという事実は既にVCLによって課されているので、これは問題ではありません。しかし、あなたのソリューションはちょうどきれいに感じるので、明日それを試してみましょう。 –

0

RecreateWndを呼び出す前に、Associateプロパティの値をローカル変数に格納してから、後で設定してください。

+0

問題は、アップダウンがそのバディを知っているが、その逆ではなく、RecreateWndがバディによって発行されているということです。 –

2

TCustomUpDown.SetAssociateがupdownとbuddyが同じ親を持つことを確認し、これを使用して重複した関連付けを避ける方法を知りました。だから私は自分自身のRecreateWndメソッドを呼び出すことを試みた:

procedure TAlignedEdit.RecreateWnd; 
var 
    i: Integer; 
    c: TControl; 
    ud: TCustomUpDown; 
begin 
    ud := nil; 
    for i := 0 to Pred(Parent.ControlCount) do 
    begin 
    c := Parent.Controls[i]; 
    if c is TCustomUpDown then 
     if THACK_CustomUpDown(c).Associate = Self then 
     begin 
     ud := TCustomUpDown(c); 
     Break; 
     end; 
    end; 
    inherited RecreateWnd; 
    if Assigned(ud) then 
    begin 
    THACK_CustomUpDown(ud).Associate := nil; 
    THACK_CustomUpDown(ud).Associate := Self; 
    end; 
end; 

et voila - それは働く!

関連する問題