Autor Beitrag
stschemel
Hält's aus hier
Beiträge: 7

WIN 2000, WIN XP, Linux
D7 Prof
BeitragVerfasst: Mi 09.02.05 16:52 
Hi!

Kennt jemand eine Combobox, die die Listeneinträge automatisch filtert?

Das soll so funktionieren: wenn man im Textfeld einen String eingibt (z.B. eine 1), dann wird in der Liste nur noch das angezeigt, wo eine 1 vorkommt, alle anderen sollten ausgeblendet oder deaktiviert sein.

Bei den "üblichen Verdächtigen" (Jedi, Torry, LMD, Orpheus) habe ich nichts gefunden.

Tschau
Steffen
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Do 10.02.05 16:53 
lade die listeneinträge in eine stringlist und je nach user-eingabe werden dann nur die items geladen die mit dem string beginnen.
stschemel Threadstarter
Hält's aus hier
Beiträge: 7

WIN 2000, WIN XP, Linux
D7 Prof
BeitragVerfasst: Do 10.02.05 17:34 
retnyg hat folgendes geschrieben:
lade die listeneinträge in eine stringlist und je nach user-eingabe werden dann nur die items geladen die mit dem string beginnen.

Hallo!

Im Prinzip ist mir das auch klar (davon mal abgesehen, das ich die Liste nach den Strings filtern muß, in denen die Eingabe (irgendwo) vorkommt, nicht nur am Anfang).
Da ich aber ungefähr 50 Comboboxen habe, die ich so behandeln müßte, werde ich wohl eine eigene Komponente schreiben. Diese wird dann ein Property haben (Filtered), je nachdem wie dieses gesetzt ist, verhält sich die Combobox wie bisher (filtered=false, default) oder bei filtered=true wird die Liste halt subgefiltert.

Ich dachte halt, ich kann mir den Aufwand sparen (Wozu das Rad neu erfinden... aber wenn es so ein Rad noch nicht gibt?).

Tschau
Steffen
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Do 10.02.05 17:36 
nun, ich kenne kein solchiges rad ;)
stschemel Threadstarter
Hält's aus hier
Beiträge: 7

WIN 2000, WIN XP, Linux
D7 Prof
BeitragVerfasst: Mo 14.02.05 17:54 
retnyg hat folgendes geschrieben:
nun, ich kenne kein solchiges rad ;)

Hallo nochmal!

Ich habe mir jetzt ein solches Rad gebaut, allerdings hats noch ein paar Schönheitsfehler (Abspeichern der Listen in statischen Arrays, da ich bei der Verwendung einer Tstrings oder TStringlist in eigenen Komponenten ständig Fehlermeldungen erhalte (abstrakter Fehler oder EA-Fehler auf 0)). Auch bringt er dann die Indexverwaltung durcheinander (es wird ja dann neu durchgezählt!), also werde ich die Indizes nochmal extra mit Abspeichern.

Wenn ichs fertig habe, melde ich mich noch einmal.
Steffen :)
stschemel Threadstarter
Hält's aus hier
Beiträge: 7

WIN 2000, WIN XP, Linux
D7 Prof
BeitragVerfasst: Mo 28.02.05 11:19 
stschemel hat folgendes geschrieben:
retnyg hat folgendes geschrieben:
nun, ich kenne kein solchiges rad ;)

Hallo nochmal!

Ich habe mir jetzt ein solches Rad gebaut, allerdings hats noch ein paar Schönheitsfehler (Abspeichern der Listen in statischen Arrays, da ich bei der Verwendung einer Tstrings oder TStringlist in eigenen Komponenten ständig Fehlermeldungen erhalte (abstrakter Fehler oder EA-Fehler auf 0)). Auch bringt er dann die Indexverwaltung durcheinander (es wird ja dann neu durchgezählt!), also werde ich die Indizes nochmal extra mit Abspeichern.

Wenn ichs fertig habe, melde ich mich noch einmal.
Steffen :)


Ich zitier mich mal selber... Also das Rad ist sozusagen fertig, nur funktioniert es noch immer intern nicht mit Stringlisten (das erzeugt immer Laufzeitfehler), sondern mit dynamischen Arrays of String (ist nicht ganz so elegant).

Der Code sieht dann so aus...

ausblenden volle Höhe 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:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
unit ComboBox1;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, graphics, windows;

type

  TStFilterComboBox = class(TComboBox)
  private
    { Private-Deklarationen }
     isfiltered : boolean;
     intfiltered : boolean;
     inttext : string;
     strglist_intern : array of string;   //Komplettliste
     strglist_intern_filtered : array of string//gefilterte Liste
     itemlist_filtered : array of integer; //Originalitemliste
     listlaenge, maxlaenge : integer;
     ffiltercolor : tcolor;
     scolor : tcolor;
     procedure setfiltered (input : boolean);
     procedure filter_list (input : string);
     procedure filtern(input : string);
     function GetItemIndex : integer;
     procedure SetItemIndex (input : integer);
     function getfiltercolor : tcolor;
     procedure setfiltercolor (input : tcolor);
  protected
    { Protected-Deklarationen }
    procedure KeyPress(var Key: Char); override;
  public
    { Public-Deklarationen }
    constructor create (AOwner : TComponent); virtual;
    destructor destroy (AOwner : TComponent); virtual;
    procedure clear; virtual;
    property ItemIndex: Integer read GetItemIndex write SetItemIndex;
  published
    { Published-Deklarationen }
    property Filtered : boolean read isfiltered write setfiltered default false;
    property FilterColor : TColor read getfiltercolor write setfiltercolor default clskyblue;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Steffens', [TStFilterComboBox]);
end;

constructor tStFilterComboBox.create (AOwner : TComponent);
begin
  //geerbte Methode aufrufen
  inherited create(AOwner);
  intfiltered := false;
end;

function tStFilterComboBox.getfiltercolor : tcolor;
begin
  result := ffiltercolor;
end;

procedure  tStFilterComboBox.setfiltercolor(input : tcolor);
begin
  scolor := color;
  ffiltercolor := input;
end;

destructor tStFilterComboBox.destroy(AOwner : TComponent);
begin
  //geerbte destroy-Methode aufrufen
  inherited destroy;
end;

procedure tStFilterComboBox.setfiltered (input : boolean);
begin
 if isfiltered <> input then
  isfiltered := input;
end;

procedure tStFilterComboBox.clear ;
begin
  //geerbte Methode aufrufen
  inherited clear;
end;

procedure tStFilterComboBox.filtern(input : string);
var i,j : integer;
    strg : string;
begin
  i := items.Count ;
  listlaenge := 0;
  for j := 0 to i - 1 do
  begin
    strg := items[j];
    if pos(input,strg) <> 0 then
    begin
      setlength(strglist_intern_filtered,listlaenge + 1);
      strglist_intern_filtered[listlaenge] := strg;
      //Original-Itemindizes abspeichern
      setlength(itemlist_filtered,listlaenge + 1);
      itemlist_filtered[listlaenge] := j;
      listlaenge := listlaenge + 1;
    end;
  end;
end;

procedure tStFilterComboBox.filter_list (input : string);
var j : integer;
begin
  if intfiltered = false then
  begin
   for j := 0 to items.Count -1 do
   begin
    setlength(strglist_intern,j + 1);
    strglist_intern[j] := items[j];
   end;
   maxlaenge := items.Count;
  end;
  //Filtern
  filtern (input);
  //Wenn kein Text eingegeben ist, dann alle Strings anzeigen
  if (input = ''or (listlaenge = 0then
  begin
    text := '';
    //Farbe setzen
    color := scolor;
    items.clear;
    for j := 0 to maxlaenge -1 do
    begin
      items.add(strglist_intern[j]);
    end;
    intfiltered := false;
    if autodropdown = true then
    begin
      if maxlaenge < 30 then
      begin
        dropdowncount := maxlaenge;
      end
      else
      begin
        dropdowncount := 30;
      end;
      droppeddown := false;
      droppeddown := true;
    end;
  end
  else
  begin
    //Farbe setzen
    color := ffiltercolor;
    items.Clear;
    //selstart := 100;
    for j := 0 to listlaenge - 1 do
    begin
      items.add(strglist_intern_filtered[j]);
    end;
    intfiltered := true;
    if autodropdown = true then
    begin
      if listlaenge < 30 then
      begin
        dropdowncount := listlaenge;
      end
      else
      begin
        dropdowncount := 30;
      end;
      droppeddown := false;
      droppeddown := true;
    end;
  end;
end;

procedure tStFilterComboBox.KeyPress(var key : char);
begin
//Filtern                       
  if filtered = true then
  begin
    if (ord(key) > ord('!')) and (ord(key) < ord('}') )then
    begin
      inttext := inttext + key;
      filter_list(inttext);
      text := '';
      text := copy(inttext,0,length(inttext)-1);
      selstart := length(inttext);
    end
    else
    begin
      if key = chr(vk_back) then
      begin
        inttext := copy(inttext,0,length(inttext)-1);
      end;
      if (key = chr(vk_clear)) or (key = chr(vk_escape)) then
      begin
        inttext := '';
      end;
      filter_list(inttext);
      text := '';
      text := copy(inttext,0,length(inttext)-1);
      selstart := length(inttext);
    end;
  end;
//Den Rest auch noch durchführen
  inherited keypress(key);
end;

function tStFilterComboBox.GetItemIndex;
var indx : integer;
begin
  indx := inherited itemindex;
  if intfiltered = true then
  begin
    result := itemlist_filtered[indx];
  end
  else
  begin
    result := indx;
  end;
end;

procedure tStFilterComboBox.SetItemIndex(input : integer);
begin
  inherited itemindex := input;
end;

end.


Ich baue nicht jeden Tag Komponenten, wenn Ihr noch Fehler order Verbesserungsmöglichkeiten findet, schreibts mir bitte.

Die Komponente verhält sich in der Grundeinstellung wie die Standard-Delphi-Combobox. Mit Filtercolor kann die Farbe eingestellt werden, mit der die Box eingefärbt wird, falls ein passender Eintrag gefunden wurde. Mit Filtered kann umgeschalten werden, ob nach Substrings gefiltert werden soll oder nicht.

Tschüß
Steffen :lol:

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.