1

Associate が TEdit サブクラスのインスタンスに設定されている TUpDown コントロールがあります。編集クラスは、オーバーライドされた DoEnter メソッドで RecreateWnd を呼び出します。残念ながら、これは API レベルでバディ接続を強制終了し、上向き矢印をクリックしたときなどに奇妙な動作を引き起こします。

私の問題は、編集インスタンスが、再接続するアップダウンのバディであることを認識せず、バディの喪失がアップダウンに通知されないことです。2つを再接続する方法はありますか?

4

3 に答える 3

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-動作します!

于 2009-09-01T13:14:32.660 に答える
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;
于 2009-09-01T17:37:37.130 に答える
0

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

于 2009-09-01T12:54:13.917 に答える