Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Wie kann man Property ImageIndex mit ImageList verbinden?


Nostromo - Mo 29.12.08 23:45
Titel: Wie kann man Property ImageIndex mit ImageList verbinden?
Ihr kennt doch auch diese Buttons, bei denen man ein Property "Images" mit einer Imagelist besetzen kann und mithilfe des
Properties "ImageIndex" den Index des Bildes innerhalb der Imageliste.
Zwar ist Imageindex ein integer, aber wenn man das Feld anklickt, dann öffnet sich ein dropdown mit all den bildern der
Imageliste.
Ich bin mir sicher das ich dieses Verhalten schon einmal in einer Komponente realisiert habe, allerdings finde ich
rein gar nichts zu diesem Thema. Auch das durchforsten des Delphi-Quellcodes oder diverser anderer Komponenten hilft
mir nicht weiter. In den jeweiligen Komponenten finde ich einfach keine Verbindung zwischen "ImageIndex" und der "Imageliste". :?!?:
( z.B. JvTransparentButton)
Ich bin mir fast 100% sicher das war was total stupid einfaches :nut: .
Kann natürlich sein das ich einfach die falschen Suchwörter bei Google eingebe. Normalerweise finde ich da immer was.

Kann mir vielleicht einer von euch kurz den Weg leuchten? :roll:


jaenicke - Mo 29.12.08 23:56

Schau mal hier, unter anderem die ersten beiden Ergebnisse sollten helfen, das ist ein sogenannter Property Editor:
Suche bei Google DELPHI PROPERTY EDITOR COMBOBOX
http://www.delphi3000.com/articles/article_2744.asp?SK=
http://www.howtodothings.com/computers/a1228-simple-combobox-property-editor.html
Das steckt nicht in der entsprechenden Komponente ;-).


Xentar - Mo 29.12.08 23:56

Verstehe ich das richtig: Du möchtest eine eigene Komponente entwickeln, die ebenfalls diese Properties "ImageIndex" enthält, und sich dieses genau so verhält?


Nostromo - Di 30.12.08 00:47

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Verstehe ich das richtig: Du möchtest eine eigene Komponente entwickeln, die ebenfalls diese Properties "ImageIndex" enthält, und sich dieses genau so verhält?


Ja, ich habe eine Komponente TTransButton geschrieben. Diese enthält bereits eine Imagelist und die
beiden Properties ImageIndex und ImageDisabledIndex.

Allerdings verhalten sich die beiden Index-Integer im Property-Editor genauso wie ein Integerwert: man kann eine Zahl eingeben.
:shock:

Wenn man sich in der JVCL den JvTransparentButton ansieht wird man feststellen, das dieser Button ebenfalls pure Integerwerte
als Properties benutzt. Bei diesem Button verhält sich jedoch der Objekt-Editor anders. Dort klappt eine Liste mit den Images
auf (eine Combobox mit Indexangabe und den entsprechenden Images).
Es gibt im Quellcode jedoch absolut keine Verbindung zwischen dem Property "Imageindex" und der Imageliste, ausser natürlich beim
Zeichnen des Buttons.


Nostromo - Di 30.12.08 00:49

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Schau mal hier, unter anderem die ersten beiden Ergebnisse sollten helfen, das ist ein sogenannter Property Editor:
Suche bei Google DELPHI PROPERTY EDITOR COMBOBOX
http://www.delphi3000.com/articles/article_2744.asp?SK=
http://www.howtodothings.com/computers/a1228-simple-combobox-property-editor.html
Das steckt nicht in der entsprechenden Komponente ;-).


Ja, das kenne ich. Man braucht aber für den von mir benannten Fall keinen Property-Editor zu schreiben (siehe Hinweis auf die
offenen Quellen der JVCL). Es gibt da einen Trick an den ich mich jetzt leider nicht mehr erinnere.


jaenicke - Di 30.12.08 00:49

Der Propertyeditor überprüft, ob es sich um eine bestimmte Komponente handelt vermute ich. Ich kann ja mal schauen wo der Property Editor definiert ist.


Xentar - Di 30.12.08 01:00

Bei den anderen Komponenten ist ImageIndex jeweils vom Typ TImageIndex und nicht einfach nur integer
vielleicht hilft das schon?

Edit:
Hm, glaub da muss man beim registrieren der Komponenten auch noch zusätzlich diesen PropertyEditor registrieren.


jaenicke - Di 30.12.08 01:10

Die entsprechenden Editoren finden sich, wenn ich das beim ersten Überfliegen richtig gesehen habe, in JvInspExtraEditors.pas und JvInspector.pas.
Genauer habe ich mir das noch nicht angeschaut.

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Edit:
Hm, glaub da muss man beim registrieren der Komponenten auch noch zusätzlich diesen PropertyEditor registrieren.
Ganz genau!


Nostromo - Di 30.12.08 01:18

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Bei den anderen Komponenten ist ImageIndex jeweils vom Typ TImageIndex und nicht einfach nur integer
vielleicht hilft das schon?

Edit:
Hm, glaub da muss man beim registrieren der Komponenten auch noch zusätzlich diesen PropertyEditor registrieren.


Jo, du hast recht. :oops:
Hab mal das Property bei mir auf TImageIndex gewechselt und schon taucht eine Dropdownliste auf. Allerdings fehlt noch die
richtige Connection, denn es kommen keine Bilder.

Huch: TImageIndex ist definiert als "Integer" in Delphis "ImgList"-Unit.


jaenicke - Di 30.12.08 01:20

user profile iconNostromo hat folgendes geschrieben Zum zitierten Posting springen:
Huch: TImageIndex ist definiert als "Integer" in Delphis "ImgList"-Unit.
Ja, natürlich. Der spezielle Typ ist nur notwendig, damit Delphi "weiß", dass bei diesem speziellen Integer der Propertyeditor angezeigt werden soll. ;-)

Wie die Dropdownliste gefüllt wird, müsste ich allerdings erstmal schauen.


Nostromo - Di 30.12.08 01:44

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconNostromo hat folgendes geschrieben Zum zitierten Posting springen:
Huch: TImageIndex ist definiert als "Integer" in Delphis "ImgList"-Unit.
Ja, natürlich. Der spezielle Typ ist nur notwendig, damit Delphi "weiß", dass bei diesem speziellen Integer der Propertyeditor angezeigt werden soll. ;-)

Wie die Dropdownliste gefüllt wird, müsste ich allerdings erstmal schauen.


Hab mal ein paar Infos aus dem Internet gelesen. So wie es aussieht, gab es mal die Möglichkeit den Delphi eigenen Editor zu nutzen ( über RegisterAsDefault )
allerdings ist diese Funktion jetzt in die Protected-Area gewandert. Ein Aufruf von ausserhalb also nicht mehr möglich.
Man muss also tatsächlich einen eigenen Editor basteln, damit es wieder funktioniert.
Dieser Editor ist in der Datei JvInspextraEditors abgebildet.
Sind nicht so viele Zeilen. Ich schauh mir das mal durch und versuche das in meiner Komponente einzuprogrammieren.
Vielleicht klappt es ja sogar :P .
Wenn nicht, wünsch ich mir den Editor nächstes Jahr zu Weihnachten. :lol:
Oder ich finde noch irgendwo einen anderen Tipp, wie man den Delphi eigenen Editor einbinden kann.

Auf jeden Fall bin ich schon sehr zufrieden mit meinem eigenen Button. der Funktioniert nicht mit festgelegten Farben, sondern passt sich perfekt der Hintergrundfarbe an, d.h. man braucht im Button nur noch die Unterschiede zum Hintergrund anzugeben. Wenn sich dann der Hintergrund ändert, passt sich der Button wie ein Chamäleon an. Selbst bei einem Bitmap oder einem Verlauf als Hintergrund klappt das.
Den hätte ich mir vor Jahren schon programmieren sollen. :wink:

Thanks für die Hilfe. Ich bleib am Thema dran, muss aber die Lösung nicht bis morgen haben. Daher kann ich mir das in Ruhe die nächsten Tage noch mal durchsehen. Ich kann ja Bescheid geben, wenn ich was finde.


Nostromo - Di 30.12.08 22:11

Habe jetzt einen eigenen Editor gebastelt.
Der von außen ansprechbare Teil des Editors steht in der Datei "MyEditorsReg.pas" und sieht so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
unit MyEditorsReg;

interface

uses Controls, DesignIntf, DesignEditors, Forms, ImgList, MyTransButton, MyImageIndexForm;

type
  TImageListIndexEditor = class(TIntegerProperty)
  public
    function getAttributes : TPropertyAttributes; override;
    procedure Edit; override;
  end;

procedure Register;

implementation

uses
  Dialogs, MyButtonTools;

{ TImageListIndexEditor }

function TImageListIndexEditor.getAttributes: TPropertyAttributes;
begin
  result := [paDialog, paMultiSelect]
end;

procedure TImageListIndexEditor.Edit;
var
  Item : TMyTransButton;
  Images : TCustomImageList;
begin
  Item := TMyTransButton(GetComponent(0));
  Images := TMyTransButton(Item).Images;
  if Images = nil then
    MessageDlg('Keine ImageListe zugewiesen.', mtInformation, [mbOK], 0)
  else
    with TImageIndexForm.Create(Application) do
    try
      ImageList1.AddImages(Images);
      FormCaptionName := 'TMyTransButton - ' + Item.Name;
      ImageIndex := GetOrdValue;
      if Showmodal = mrOk then SetOrdValue(ImageIndex);
    finally
      free;
    end;
end;

procedure Register;
begin
  RegisterPropertyEditor(TypeInfo(TMyImageIndex), TMyTransButton, '', TImageListIndexEditor);
end;


end.


Dazu gehört noch das EditorFormular in "MyImageIndexForm".

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
unit MyImageIndexForm;

interface

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

type
  TImageIndexForm = class(TForm)
    ImageList1: TImageList;
    ListView1: TListView;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ListView1SelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure ListView1DblClick(Sender: TObject);
  private
    { Private-Deklarationen }
    FFormCaptionName : string;
    FImageIndex : integer;
    procedure SetFormCaptionName(const Value:string);
    procedure SetImageIndex(const Value:integer);
  public
    { Public-Deklarationen }
    property FormCaptionName : string read FFormCaptionName write SetFormCaptionName;
    property ImageIndex : integer read FImageIndex write SetImageIndex;
  end;

var
  ImageIndexForm: TImageIndexForm;

implementation

{$R *.dfm}

{ TImageIndexForm }

procedure TImageIndexForm.SetFormCaptionName(const Value: string);
begin
  Caption := Value + '.ImageIndex ';
end;

procedure TImageIndexForm.SetImageIndex(const Value: integer);
begin
  FImageIndex := Value;
end;

procedure TImageIndexForm.FormCreate(Sender: TObject);
begin
  FImageIndex := -1;
end;

procedure TImageIndexForm.FormShow(Sender: TObject);
var
  I: Integer;
  ListItem : TListItem;
begin
  with ListView1 do
  begin
    SmallImages := ImageList1;
    LargeImages := ImageList1;
    for I := 0 to ImageList1.Count-1 do
    begin
      ListItem := Items.Add;
      ListItem.Caption := 'Image ' + inttostr(i);
      ListItem.ImageIndex := i;
    end;
    if (FImageIndex <-1or (FImageIndex > ImageList1.Count-1then
    begin
      ListView1.Selected := nil;
      FImageIndex := -1;
    end else
      ListView1.Selected := ListView1.Items.Item[FImageIndex];
  end;
end;

procedure TImageIndexForm.Button1Click(Sender: TObject);
begin
  Modalresult := mrOk;
end;

procedure TImageIndexForm.Button2Click(Sender: TObject);
begin
  Modalresult := mrCancel;
end;

procedure TImageIndexForm.ListView1SelectItem(Sender: TObject;
  Item: TListItem; Selected: Boolean);
begin
  if Selected then
  begin
    FImageIndex := Item.ImageIndex;
  end;
end;

procedure TImageIndexForm.ListView1DblClick(Sender: TObject);
begin
  Modalresult := mrOk;
end;

end.



Damit mein Editor auch nur in meinen Komponenten zum tragen kommt, wird ein neuer Typ deklariert.

Delphi-Quelltext
1:
TMyImageIndex = integer;                    

den ich in den Komponenten anstelle des Typs TImageIndex verwende.
Das wars schon.
Wenn ich jetzt ein Bild wählen muss, geht ein komfortabel großes Formular mit einer tollen Übersicht auf und ich wähle einfach
mit doppelklick was ich haben will. :D

Dankeschön an Jaenicke und Xentar für die Hinweise. Sonst würde ich wahrscheinlich morgen noch weitersuchen. :lol:

gruß
Jürgen