2012-12-19 29 views
10

Tôi đã làm theo một số hướng dẫn về cách tạo hộp thoại trình chỉnh sửa thuộc tính tùy chỉnh, nhưng có quá nhiều thứ liên quan đến việc tôi không thể làm cho nó hoạt động đúng. Những gì tôi đang cố gắng thực hiện là một biểu mẫu tùy chỉnh với một bộ chọn ngày (lịch), bộ chọn thời gian, và các nút OK và Hủy. Biểu mẫu không có vấn đề gì cả, nhưng làm thế nào tôi có thể thực hiện điều này để tôi có thể xuất bản một thuộc tính trong bất kỳ thành phần nào của một kiểu nào đó bằng một nút để khởi chạy trình soạn thảo thuộc tính?Làm cách nào để triển khai trình chỉnh sửa thuộc tính tùy chỉnh của riêng tôi cho tất cả các phiên bản của một loại nhất định?

Tôi muốn ghi đè hoàn toàn loại TDateTime và đặt trình chỉnh sửa tùy chỉnh của mình vào vị trí của nó, vì vậy bất cứ nơi nào TDateTime được xuất bản và hiển thị trong Trình kiểm tra đối tượng, tôi có thể sử dụng trình chỉnh sửa này để sửa đổi cả ngày và giờ cùng nhau cửa sổ.

Vấn đề là tài liệu về cách tạo trình chỉnh sửa thuộc tính tùy chỉnh kém và mặc dù một số tài nguyên rất kỹ lưỡng, chúng đi vào quá nhiều chi tiết về khả năng và thiếu tính đến các trường hợp phổ biến nhất.

Trả lời

14

Tôi không muốn đặt câu hỏi này ở đây và mong đợi bất cứ ai trả lời cho tôi, vì vậy tôi đã tự nghiên cứu để giải quyết các vấn đề của mình và tôi muốn chia sẻ kinh nghiệm độc đáo liên quan đến dự án nhỏ này, như tôi ' m chắc chắn những người khác đang thất vọng với cùng một điều.

Có nhiều khả năng khác nhau với trình chỉnh sửa thuộc tính tùy chỉnh, hộp thoại và trình chỉnh sửa thành phần. Điều này đặc biệt sẽ kêu gọi một hậu duệ TDateTimeProperty. Điều này sẽ cho phép bạn có thể chỉnh sửa giá trị của thuộc tính trực tiếp trong Object Inspector dưới dạng văn bản thuần túy (String) trong khi vẫn giữ định dạng DateTime.

Tôi giả định rằng bạn đã có kiến ​​thức chung về việc tạo thành phần tùy chỉnh và gói mà bạn có thể xuất bản trình chỉnh sửa thuộc tính này, vì đó là bài học mà tôi sẽ không đề cập đến. Lệnh này chỉ gọi một dòng mã được đặt bên trong quy trình Register, nhưng chúng tôi sẽ thực hiện điều đó sau.

Trước tiên, bạn cần tạo biểu mẫu mới trong gói Design-Time, nơi các thành phần của bạn được đăng ký. Đặt tên cho đơn vị DateTimeProperty.pas và đặt tên cho biểu mẫu DateTimeDialog (do đó tạo lớp học của biểu mẫu TDateTimeDialog). Nơi bất cứ điều gì bạn cần kiểm soát, trong trường hợp này một (set với Kind-dtkTime) TMonthCalendar, TDateTimePicker, và 2 TBitBtn điều khiển, một nhãn OK với ModalResult của mrOK và người kia dán nhãn Cancel với ModalResult của mrCancel.

đơn vị bạn nên tìm một cái gì đó như thế này:

unit DateTimeProperty; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
    System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, 
    Vcl.ComCtrls, Vcl.StdCtrls, Vcl.Buttons; 

type 
    TDateTimeDialog = class(TForm) 
    dtDate: TMonthCalendar; 
    dtTime: TDateTimePicker; 
    BitBtn1: TBitBtn; 
    BitBtn2: TBitBtn; 
    private 

    public 

    end;   

var 
    DateTimeDialog: TDateTimeDialog; 

implementation 

{$R *.dfm} 

end. 

Và đây là DFM mã sau mẫu đơn này:

object DateTimeDialog: TDateTimeDialog 
    Left = 591 
    Top = 158 
    BorderIcons = [biSystemMenu] 
    BorderStyle = bsToolWindow 
    Caption = 'Pick Date/Time' 
    ClientHeight = 231 
    ClientWidth = 241 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    Position = poScreenCenter 
    DesignSize = (
    241 
    231) 
    PixelsPerInch = 96 
    TextHeight = 13 
    object dtDate: TMonthCalendar 
    Left = 8 
    Top = 31 
    Width = 225 
    Height = 166 
    Anchors = [akLeft, akRight, akBottom] 
    Date = 41261.901190613430000000 
    TabOrder = 1 
    end 
    object dtTime: TDateTimePicker 
    Left = 8 
    Top = 8 
    Width = 113 
    Height = 21 
    Date = 41261.000000000000000000 
    Time = 41261.000000000000000000 
    Kind = dtkTime 
    TabOrder = 2 
    end 
    object BitBtn1: TBitBtn 
    Left = 158 
    Top = 200 
    Width = 75 
    Height = 25 
    Caption = 'OK' 
    Default = True 
    ModalResult = 1 
    TabOrder = 0 
    end 
    object BitBtn2: TBitBtn 
    Left = 77 
    Top = 200 
    Width = 75 
    Height = 25 
    Caption = 'Cancel' 
    ModalResult = 2 
    TabOrder = 3 
    end 
end 

Bây giờ, thêm DesignEditorsDesignIntf quy định tại khoản uses của bạn. Đảm bảo bạn có số DesignIDE được khai báo trong số Requires của gói Design-Time này. Điều này là bắt buộc để xuất bản bất kỳ trình chỉnh sửa thuộc tính nào.

Trong biểu mẫu, hãy tạo thuộc tính công khai mới được gọi là DateTime loại TDateTime bằng trình khởi động và thiết lập thuộc tính. Thuộc tính này sẽ cho phép bạn dễ dàng đọc/ghi giá trị TDateTime đầy đủ mà lựa chọn thực sự đại diện.Vì vậy, bạn nên có điều này trong biểu mẫu của mình:

private 
    function GetDateTime: TDateTime; 
    procedure SetDateTime(const Value: TDateTime); 
public 
    property DateTime: TDateTime read GetDateTime write SetDateTime; 

.... 

function TDateTimeDialog.GetDateTime: TDateTime; 
begin 
    Result:= Int(dtDate.Date) + Frac(dtTime.Time); 
end; 

procedure TDateTimeDialog.SetDateTime(const Value: TDateTime); 
begin 
    dtDate.Date:= Value; 
    dtTime.DateTime:= Value; 
end; 

Tiếp theo, chúng tôi cần thêm lớp trình chỉnh sửa thuộc tính thực tế. Tạo lớp này chỉ dưới {$R *.dfm} mà chỉ là dưới implementation:

type 
    TDateTimeEditor = class(TDateTimeProperty) 
    public 
    procedure Edit; override; 
    function GetAttributes: TPropertyAttributes; override; 
    function GetValue: String; override; 
    procedure SetValue(const Value: String); override; 
    end; 

procedure TDateTimeEditor.Edit; 
var 
    F: TDateTimeDialog; 
begin 
    //Initialize the property editor window 
    F:= TDateTimeDialog.Create(Application); 
    try 
    F.DateTime:= GetFloatValue; 
    if F.ShowModal = mrOK then begin 
     SetFloatValue(F.DateTime); 
    end; 
    finally 
    F.Free; 
    end; 
end; 

function TDateTimeEditor.GetAttributes: TPropertyAttributes; 
begin 
    //Makes the small button show to the right of the property 
    Result := inherited GetAttributes + [paDialog]; 
end; 

function TDateTimeEditor.GetValue: String; 
begin 
    //Returns the string which should show in Object Inspector 
    Result:= FormatDateTime('m/d/yy h:nn:ss ampm', GetFloatValue); 
end; 

procedure TDateTimeEditor.SetValue(const Value: String); 
begin 
    //Assigns the string typed in Object Inspector to the property 
    inherited; 
end; 

Cuối cùng, chúng ta cần thêm một thủ tục Register để thực hiện việc đăng ký thực tế của biên tập viên bất động sản mới này:

procedure Register; 
begin 
    RegisterPropertyEditor(TypeInfo(TDateTime), nil, '', TDateTimeEditor); 
end; 

Bây giờ có một phần quan trọng cần hiểu trong cuộc gọi này đến RegisterPropertyEditor. Vì tham số thứ 2 và thứ 3 là nil và một chuỗi trống, điều này có nghĩa là trình chỉnh sửa sẽ áp dụng cho tất cả các phiên bản TDateTime. Xem xét thủ tục này để biết thêm thông tin về cách làm cho nó cụ thể cho các thành phần nhất định và các thể hiện thuộc tính.

Và đây là kết quả cuối cùng sau khi cài đặt ...

Sample of final property editor

Một số nguồn lực tốt cho các biên tập viên sở hữu tùy chỉnh mà đóng góp như sau:

  1. how to make custom component property?
  2. http://delphi.about.com/library/bluc/text/uc092501d.htm
  3. http://www.sandownet.com/propedit.html
+0

nguồn lực tốt hơn có thể FLOSS thư viện như CnWizards hoặc JediVCL, mà thực hiện và đăng ký một số biên tập viên bất động sản toàn cầu, chỉ cần đọc và học hỏi –

+0

Và đừng quên Ray Konopka của [Phát triển Tuỳ chỉnh Delphi 3 Components] (http: // www .amazon.com/Visual-Developer-Developing-Custom-Components/dp/1576101126 /) D3 và không còn in, nhưng vẫn áp dụng được. Ray có một phiên bản pdf để bán trên trang web của mình: http://www.raize.com/DevTools/Ordering/Pricing.asp –

+0

+1 Được thực hiện tốt. Thay đổi thứ tự của các điều khiển thời gian và ngày mặc dù ... ;-) – NGLN

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