2012-12-19 18 views
10

Ich habe ein paar Tutorials zum Erstellen eines benutzerdefinierten Eigenschaftseditordialogs verfolgt, aber es gibt so viele Dinge, die ich nicht richtig funktionierte. Was ich versuche, ist ein benutzerdefiniertes Formular mit einer Datumsauswahl (Kalender), einer Zeitauswahl und OK und Abbrechen-Schaltflächen. Das Formular ist überhaupt kein Problem, aber wie würde ich das implementieren, damit ich eine Eigenschaft in einer beliebigen Komponente eines bestimmten Typs mit einer Schaltfläche veröffentlichen kann, um den Eigenschaftseditor zu starten?Wie kann ich meinen eigenen benutzerdefinierten Eigenschaftseditor für alle Instanzen eines bestimmten Typs implementieren?

ich vollständig die TDateTime Art außer Kraft zu setzen und legte meinen benutzerdefinierten Editor an seinem Platz, so überall dort, wo ein TDateTime veröffentlicht und sichtbar im Objektinspektor möchte ich mit diesem Editor kann sowohl Datum und Zeit zusammen in der gleichen ändern Fenster.

Das Problem ist, dass die Dokumentation zum Erstellen eines benutzerdefinierten Eigenschaftseditors schlecht ist und obwohl einige Ressourcen sehr gründlich sind, gehen sie zu sehr ins Detail der Fähigkeiten und kommen nicht zu dem Punkt in den häufigsten Szenarien.

Antwort

14

Ich wollte diese Frage hier nicht stellen und erwarten, dass jemand sie für mich beantwortet, also habe ich die Forschung selbst gemacht, um meine Probleme zu lösen, und ich möchte die einzigartige Erfahrung dieses Mini-Projekts teilen. Ich bin sicher, dass andere mit der gleichen Sache frustriert sind.

Es gibt viele verschiedene Möglichkeiten mit benutzerdefinierten Eigenschaftseditoren, Dialogen und Komponenteneditoren. Dies würde insbesondere einen TDateTimeProperty Nachkommen erfordern. Auf diese Weise können Sie den Wert der Eigenschaft direkt im Objektinspektor als Nur-Text (String) bearbeiten und gleichzeitig die DateTime-Formatierung beibehalten.

Ich gehe davon aus, dass Sie bereits allgemeine Kenntnisse über das Erstellen von benutzerdefinierten Komponenten und ein Paket, in dem Sie diesen Eigenschaftseditor veröffentlichen können, haben, denn das ist eine Lektion, die ich nicht behandeln werde. Dies erfordert, dass nur eine Codezeile innerhalb der Register-Prozedur platziert wird, aber wir werden später darauf eingehen.

Zuerst müssen Sie ein neues Formular in Ihrem Design-Time Paket erstellen, in dem Ihre Komponenten registriert sind. Nennen Sie die Einheit DateTimeProperty.pas, und nennen Sie das Formular DateTimeDialog (damit wird die Formularklasse TDateTimeDialog). Platz, was steuert die Sie benötigen, in diesem Fall ein TMonthCalendar, TDateTimePicker (mit Kind Set dtkTime) und 2 TBitBtn Kontrollen, ein markierten OK mit ModalResult von mrOK und anderen Cancel mit ModalResult von mrCancel markiert.

Ihr Gerät sollte wie folgt aussehen:

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. 

Und hier ist der DFM Code hinter dieser Form:

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 

Nun fügen DesignEditors und DesignIntf auf Ihre uses Klausel. Stellen Sie sicher, dass Sie im Requires dieses Design-Time Pakets angegeben haben. Dies ist erforderlich für die Veröffentlichung von Immobilien-Editoren. Erstellen Sie im Formular eine neue öffentliche Eigenschaft namens DateTime vom Typ TDateTime mit einer Eigenschaft Getter und Setter. Mit dieser Eigenschaft können Sie den gesamten TDateTime Wert, den die Auswahl tatsächlich darstellt, problemlos lesen/schreiben.So sollten Sie dies in Ihrem Formular haben:

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; 

Als nächstes müssen wir die tatsächliche Eigenschaft Editor-Klasse hinzufügen. Erstellen Sie diese Klasse nur unter dem {$R *.dfm} die knapp implementation ist:

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; 

Schließlich müssen wir ein Register Verfahren fügen Sie die eigentliche Registrierung dieser neuen Eigenschaftseditor auszuführen:

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

Jetzt gibt es eine wichtiges Stück in diesem Anruf zu RegisterPropertyEditor zu verstehen. Da der 2. und 3. Parameter nil und eine leere Zeichenfolge ist, bedeutet dies, der Editor für alle Instanzen von TDateTime gelten. Sehen Sie sich diese Prozedur an, um weitere Informationen zu bestimmten Komponenten und Eigenschaftsinstanzen zu erhalten.

Und hier ist das Endergebnis nach der Installation von ...

Sample of final property editor

Einige gute Ressourcen für benutzerdefinierte Eigenschaft Editoren, die beigetragen haben, sind wie folgt:

  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

Weitere gute Quellen können FLOSS-Bibliotheken wie CnWizards oder JediVCL sein, die einige globale Eigenschaftseditoren implementieren und registrieren, nur lesen und lernen –

+0

Und nicht vergessen, Ray Konopka [Entwickeln von benutzerdefinierten Delphi 3 Komponenten] (http: // www .amazon.com/Visuell-Entwickler-Entwicklung-Custom-Komponenten/dp/1576101126 /) D3 und nicht mehr in gedruckter Form, aber immer noch anwendbar. Ray hat eine PDF-Version zum Verkauf auf seiner Website: http://www.raize.com/DevTools/Ordering/Pricing.asp –

+0

+1 Gut gemacht. Wäre die Reihenfolge der Zeit und das Datum Kontrollen allerdings ändern ... ;-) – NGLN