4

概要

TCustomTreeView から派生するコンポーネントを作成しています。オブジェクト インスペクタにドロップダウン リスト (paValueList?) を表示するプロパティを追加したいと考えています。このリストは、自分のコントロールにアタッチされている別のリスト (TStrings) に基づいて動的に設定する必要があります。たとえば、TComboBox、TListBox の項目、または TStringList の文字列などです。

私はいくつかの問題を抱えていますが、いくつかのガイダンスとアドバイスがあれば本当にできます.


コードのレイアウト

読みやすくするためにコードを短くしましたが、レイアウトは基本的に私が持っているものと同じです。

コンポーネント パッケージを 2 つ (同じプロジェクト グループ) に分けPackage1、コンポーネント コード (たとえば、TCustomTreeView から派生したコンポーネント) で構成しPackage2、登録手順とデザイナー ユニット (designide.dcp、DesignIntf​​、DesignEditors など) を含めます。

Package2の TCustomTreeView から派生したコンポーネントに使用されるプロパティ エディタを追加する必要があると思われる場所ですPackage1

パッケージ1

unit MyTreeViewUnit;

implementation

uses
  ...
  Classes,
  SysUtils;

type
  TMyTreeView = class(TCustomTreeView)
  private
    FSomeList: TStringList; // property editor should be filled using this list
    procedure SetSomeList(const Value: TStringList);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property SomeList: TStringList read FSomeList write SetSomeList;
  end;

  ....

パッケージ2

unit MyTreeViewPropUnit;

implementation

uses
  DesignIntf,
  DesignEditors,
  Classes;

type
  TMyTreeViewProperty = class(TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure GetValues(Proc: TGetStrProc); override;
    procedure Edit; override;
  end;

implementation

uses
  MyTreeViewUnit;  

function TMyTreeViewProperty.GetAttributes: TPropertyAttributes;
begin
  Result := [paValueList]; ?
end;

procedure TMyTreeViewProperty.GetValues(Proc: TGetStrProc);
begin
  inherited;
  // These cannot be added here!!
  // This list should be populated based on SomeList found in Package1 - MyTreeViewUnit.pas
  Proc('Item1');
  Proc('Item2');
end;

procedure TMyTreeViewProperty.Edit;
begin
  inherited;
  // ?
end;

unit MyCompsRegister;

interface

uses
  Classes;

procedure Register;

implementation

uses
  MyTreeViewUnit;
  MyTreeViewPropUnit;  

procedure Register;
begin
  RegisterComponents('MyTree', TMyTreeView);
  RegisterPropertyEditor(TypeInfo(String), TMyTreeView 'Test', TMyTreeView); // does not seem to add to object inspector for the component TMyTreeView
end;

end.

問題

  1. 最初の問題は、自分が行っていることが正しいアプローチであるかどうかわからないことです。私のコンポーネントはインストールされ、問題なく使用できますが、私のプロパティ エディター 'Test' は表示されません!

  2. 2 番目の問題は、GetValues が設定される方法です。いくつかの記事をオンラインで見ると、プロパティ エディターの入力などに関して、これまでの内容について基本的な洞察が得られました。最初のユニットで SomeList に割り当てられた文字列 (前に述べたように、FSomeList はたとえば TListBox である可能性があります)。

  3. これは問題 2 に関連しており、プロパティ エディタ (作業中) がツリービューと通信できるようにするにはどうすればよいですか?

誰かが私にいくつかの指針を与えることができれば、本当に感謝しています. Delphi.about や DelphiDabbler などで私が読んだものは、理解して従うのが簡単ではありません (私は混乱し、問題でかなり簡単に行き詰まります)。

どうもありがとう!

4

1 に答える 1

6

これはコメントには長すぎます。少しコードを含めたいので、ここに答えを示します。まず、あなたの質問は非常に広いです。ポイントを絞った質問ができるように、物事をブレークアップする必要があります。私は実際にあなたの2番目の質問に答え始めましたが、あきらめるずっと前に読めないものを書きました!

プロパティ エディタを必要としないコード、つまり通常の実行時コードから始める必要があります。プロパティエディタは、設計時に作業を高速化するためにのみ使用されるため、プロパティ エディタはカスタム コントロールの開発の中心になることはできません。プロパティ エディタによって行われた変更が永続的である場合、オブジェクト インスペクタに表示されるパブリッシュされたプロパティに何らかの方法で保存され (*1)、それらのプロパティは DFM ファイルに保存されます。同じプロセスが、実行時にフォームが作成されるときと、設計時にフォームを再度開くときに元に戻されます (例: IDE を閉じて再度開いた場合)。すべてを Object Inspector に入力する必要があるため、複雑なプロパティ エディターをスキップして、コントロールを機能させることができます。

これを言うようになった理由:

procedure TMyTreeViewProperty.GetValues(Proc: TGetStrProc);
begin
  inherited;
  // These cannot be added here!!
  // This list should be populated based on SomeList found in Package1 - MyTreeViewUnit.pas
  Proc('Item1');
  Proc('Item2');
end;

そのコメントは、コンポーネントを別のコンポーネントにリンクする方法をまだ理解していないことを示しています! これは実際には些細なステップであり、それが機能するようになったら、次のようにすることができます。

procedure TMyTreeViewProperty.GetValues(Proc: TGetStrProc);
var s: string;
begin
  if Assigned(FLinkedCombo) then
    for s in FLinkedCombo.Items do
      Proc(s); // Beware, written in Browser!
end;

些細なことであっても、その部分がなければ、前述の質問への回答は不完全であり、その部分にTComponent.FreeNotificationTComponent.RemoveFreeNotificationおよびTComponent.Notification!

ほとんどの作業が完了したら、作成したい任意のプロパティ エディターで作業を開始できます。その作業も通常のプロジェクトとして行われます。目的はTMyComponentsEditor、プロパティまたはコンポーネントを編集できる単純なフォーム (例) を作成することです。作業が完了したら、「この作業中のエディターを DesignTime でプロパティまたはコンポーネント エディターとして使用できるようにするにはどうすればよいですか」と尋ねることができます。

*1) 確かに、Component Editor は複数のコンポーネントを含む複雑なことを行うことができます。また、別の方法を使用して内容を永続化することもできます (つまり、単純な公開されたプロパティに依存しない)。

于 2012-12-23T19:11:39.483 に答える