2008-11-14 44 views
9

Trình kiểm tra đối tượng Delphi không hiển thị thuộc tính bổ sung của thuộc tính TFrame theo thiết kế. Mọi người có xu hướng đề xuất sử dụng một thủ thuật đã biết thường được sử dụng để hiển thị các thuộc tính của hậu duệ TForm trên thanh tra Object. Bí quyết là: đăng ký mô-đun tùy chỉnh cho con cháu TForm để Delphi IDE qua gói thời gian thiết kế như:Hiển thị thuộc tính bổ sung của thuộc tính TFrame trên thanh tra đối tượng

RegisterCustomModule(TMyFrame, TCustomModule); 

Đối tượng thanh tra có thể hiển thị thuộc tính bổ sung của dụ TFrame Hậu duệ với cách này nhưng nó sẽ mất hành vi khung của nó trong khi nó là được nhúng trong một biểu mẫu. Không thể thiết kế lại, không thể thực hiện các sự kiện cho các thành phần con của nó và nó chấp nhận các điều khiển con (mà nó không có khả năng). Nhưng nó hoạt động bình thường trong khu vực thiết kế riêng của nó.

Dường như, những hành vi được cung cấp bởi Delphi IDE đặc biệt chỉ dành cho TFrame. Họ problaly không phải là loại cơ sở chung chung.

Có cách nào khác để thực hiện việc này mà không làm mất hành vi khung không?

Tôi đang sử dụng Delphi 2007


@Tondrej,

đã đọc ý kiến ​​cho vấn đề này, cảm ơn trước.

frameunit.dfm:

object MyFrame: TMyFrame 
    Left = 0 
    Top = 0 
    Width = 303 
    Height = 172 
    TabOrder = 0 
    object Edit1: TEdit 
    Left = 66 
    Top = 60 
    Width = 151 
    Height = 21 
    TabOrder = 0 
    Text = 'Edit1' 
    end 
end 

unit frameunit; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TBaseFrame = Class(TFrame) 
    protected 
    Fstr: string; 
    procedure Setstr(const Value: string);virtual; 
    published 
    Property str:string read Fstr write Setstr; 
    End; 

    TMyFrame = class(TBaseFrame) 
    Edit1: TEdit; 
    private 
    // This won't be called in designtime. But i need this to be called in designtime 
    Procedure Setstr(const Value: string);override; 
    end; 

implementation 

{$R *.dfm} 

{ TBaseFrame } 

procedure TBaseFrame.Setstr(const Value: string); 
begin 
    Fstr := Value; 
end; 

{ TMyFrame } 

procedure TMyFrame.Setstr(const Value: string); 
begin 
    inherited; 
    Edit1.Text := Fstr; 
    // Sadly this code won't work and Edit1 won't be updated in designtime. 
end; 

end. 

unit RegisterUnit; 

interface 

procedure Register; 

implementation 

uses 
    Windows, DesignIntf, frameunit; 

procedure Register; 
var 
    delphivclide: THandle; 
    TFrameModule: TCustomModuleClass; 
begin 
    delphivclide := GetModuleHandle('delphivclide100.bpl'); 
    if delphivclide <> 0 then 
    begin 
    TFrameModule := GetProcAddress(delphivclide, '@[email protected]@'); 
    if Assigned(TFrameModule) then 
    begin 
     RegisterCustomModule(frameunit.TBaseFrame, TFrameModule); 
     // Just registering that won't cause Tmyframe to loose its frame behaviours 
     // but additional properties won't work well. 

     //RegisterCustomModule(frameunit.TMyFrame, TFrameModule); 
     // That would cause Tmyframe to lose its frame behaviours 
     // But additional properties would work well. 

    end; 
    end; 
end; 


end. 

Trả lời

0

Không, tôi không nghĩ rằng đây là hoàn toàn có thể.

Điều tôi thường làm khi có nhu cầu tương tự là chỉ cần cài đặt hậu duệ khung làm thành phần của chính quyền của nó. Nhưng vâng, theo cách đó bạn sẽ mất rất nhiều hành vi khung hình điển hình (đặc biệt là ở thời gian chết), ví dụ: bạn không còn có thể thao tác trực tiếp với các thành phần phụ và các thay đổi đối với khung không còn tự động lan truyền tới các biểu mẫu sử dụng nó ở designtime nữa - bạn phải biên dịch lại gói thời gian chạy có chứa khung đầu tiên.

Sau đó, một lần nữa, từ quan điểm OOP, điều này không quá tệ. Nó thực sự thực thi khái niệm thực hiện ẩn. Bạn vẫn có thể phơi bày các thuộc tính cá nhân và chức năng của các thành phần con thông qua các thuộc tính và phương thức mới trên chính khung đó.

4

Bạn muốn đăng ký lớp mô-đun tùy chỉnh nào cho khung của mình? Bạn đang sử dụng phiên bản Delphi nào?

Từ các thử nghiệm của tôi với Delphi 2007, lớp mô-đun tùy chỉnh có vẻ hoạt động là TFrameModule. Lớp này được chứa trong delphivclide100.bpl. Vì không có delphivclide.dcp tương ứng, bạn phải tải nó bằng tay:

unit FrameTestReg; 

interface 

procedure Register; 

implementation 

uses 
    Windows, DesignIntf, 
    FrameTest; 

procedure Register; 
var 
    delphivclide: THandle; 
    TFrameModule: TCustomModuleClass; 
begin 
    delphivclide := GetModuleHandle('delphivclide100.bpl'); 
    if delphivclide <> 0 then 
    begin 
    TFrameModule := GetProcAddress(delphivclide, '@[email protected]@'); 
    if Assigned(TFrameModule) then 
     RegisterCustomModule(TTestFrame, TFrameModule); 
    end; 
end; 

end. 

đơn vị FrameTest của tôi rất đơn giản, nó không có FrameTest.dfm, chỉ việc kê khai của các hậu duệ TFrame mới:

unit FrameTest; 

interface 

uses 
    Forms; 

type 
    TTestFrame = class(TFrame) 
    private 
    FHello: string; 
    published 
    property Hello: string read FHello write FHello; 
    end; 

implementation 

end. 

Sử dụng lớp TFrameModule, mọi thứ dường như vẫn hoạt động tốt.Tôi có thể tạo ra một hậu duệ mới của TTestFrame để đưa vào dự án và chỉnh sửa các thuộc tính đã xuất bản trong Object Inspector, đặt các thể hiện của hậu duệ mới này trên một biểu mẫu trong IDE, chỉnh sửa các thuộc tính mới được xuất bản của họ trong Object Inspector. các thành phần con của chúng, v.v. Trong tài nguyên .dfm, tôi có thể thấy chỉ thị "nội tuyến" dự kiến ​​cho các cá thể. Tôi đã không gặp phải bất kỳ vấn đề với nó cho đến nay vì vậy có lẽ đây là giải pháp.

+0

Nice, tôi havn't khung được sử dụng trong một thời gian, bởi vì tôi nghĩ rằng họ không phải là giá trị phức tạp. Nhưng tôi sẽ thử cái này. –

0
procedure TMyFrame.Setstr(const Value: string); 
begin 
    inherited; 
    Edit1.Text := Fstr; 
    // Sadly this code won't work and Edit1 won't be updated in designtime. 
end; 

Tôi nghĩ đó là vì nó không hoạt động vào thời gian thiết kế. Bạn đã đăng ký TBaseFrame dưới dạng một mô-đun tùy chỉnh, do đó, nó là thuộc tính của TBaseFrame (không phải là hậu duệ của nó!) Mà nên được chỉnh sửa tại thời điểm thiết kế. Delphi IDE chỉ biết về các thuộc tính đã xuất bản của lớp bạn đã đăng ký; nó không biết bất cứ điều gì về bất kỳ hậu duệ và ghi đè nào bạn đã thực hiện trong dự án của mình. Để thực hiện các công việc mã lúc thiết kế, bạn nên một trong hai bao gồm nó trong định nghĩa TBaseFrame:

procedure TBASEFrame.Setstr(const Value: string); 
begin 
    inherited; 
    Edit1.Text := Fstr; 
end; 

hoặc (ngoài TBaseFrame) đăng ký nghĩa TMyFrame như một module tùy chỉnh.

Cố gắng hiểu: IDE Delphi tại thời điểm thiết kế chỉ biết về những thứ đã được đăng ký trong đó. Nó không phải là một khuyết tật; đó là hành vi logic.

+1

Đã lâu rồi .. Theo tôi nhớ, Nếu tôi đăng ký TMyFrame, các cá thể của nó không có khả năng redisegnablity nữa và nó chỉ hiển thị các thuộc tính của hậu duệ của nó. – Serguzest

0

Không cần phải làm trong "cách hack"

uses 
... 
    DMForm, 
    VCLFormContainer, 
... 

procedure Register; 
begin 
... 
    RegisterCustomModule(TYourFrameClass, TFrameModule); // for frames 
    RegisterCustomModule(TYourModuleClass, TDataModuleCustomModule); // for data modules 
... 
end; 

Có một cách khác xung quanh để thêm khung hình quá

type 
    TNestableWinControlCustomModule = class (TWinControlCustomModule) 
    public 
    function Nestable: Boolean; override; 
    end; 

function TNestableWinControlCustomModule.Nestable: Boolean; 
begin 
    Result := True; 
end; 

+

RegisterCustomModule(TYourFrameClass, TNestableWinControlCustomModule); 

Tên đơn vị (được thử nghiệm trong XE7):

TCustomModule =>DesignEditors

TDataModuleCustomModule =>DMForm (designide.dcp)

TWinControlCustomModule =>WCtlForm (designide.dcp)

TFrameModule =>VCLFormContainer (vcldesigner.dcp)

Tôi giả sử rằng cho FireMonkey nó nên có thể trong cách tương tự (tìm fmxdesigner.dcp & kiểm tra những gì bên trong trong Notepad ++)

PS. Trong các phiên bản Delphi cũ đã có TDataModuleDesignerCustomModule metaclass thay vì TDataModuleCustomModule trong đơn vị DMDesigner

PPS. tên metaclass hiện khác:

TCustomFormCustomModule

TIDESourceModuleCustomModule

Các vấn đề liên quan